在微前端场景中如何共享状态?

IT技术 reactjs state micro-frontend
2021-05-26 08:27:13

第一个想法是 cookie,但您可能很快就会耗尽空间。

3个回答

有几种方法可以在微前端中进行通信。

正如已经提到的,不同的微前端应该是松散耦合的,所以你永远不会直接相互交谈。

关键问题是:您的微前端解决方案是由服务器端还是客户端组成

对于客户端,我写了一篇关于通信的文章

如果您在服务器端(由于提到 cookie,问题似乎朝着那个方向发展),那么我建议使用标准的微服务模式进行通信和交换状态。当然,在那里使用集中式系统(例如 Redis 缓存)会有所帮助。

一般来说,不同的微前端应该有自己的状态并尽可能独立。

通常你想要分享的不是状态/数据,而是带有 UI 表示的状态。原因很简单:这样您就不必处理表示和边缘情况(如果数据不可用怎么办?)。展示这一点的一个框架是Piral

希望有帮助!

没有共享状态,这会打破应该发生的隔离的概念。这种模式存在于所有微服务架构中,因为它应该消除单点故障和维护更大存储的其他复杂性。常见的方法是让每个“微前端”拥有自己的存储(即 Redux)。Redux文档对此有一个主题。

首先,您应该尽可能避免在 MicroFrontend (MFE) 之间共享状态。这是避免耦合、减少错误等的最佳实践。

很多时候您不需要它,例如,当每个 MFE 需要时,可以为每个 MFE 单独请求来自服务器的每个信息/状态(例如:“用户”信息)。

但是,如果您确实需要共享状态,则有一些解决方案,例如:

- 在 Window 对象中实现发布/订阅模式。

有一些图书馆已经提供了这一点。

//MFE 1 
import { Observable } from 'windowed-observable';

const observable = new Observable('messages');
observable.publish(input.value); //input.value markup is not present in this example for simplicity


//MFE 2 
import { Observable } from 'windowed-observable';

const observable = new Observable('messages');

const handleNewMessage = (newMessage) => {
    setMessages((currentMessages) =>  currentMessages.concat(newMessage)); //custom logic to handle the message
  };

 observable.subscribe(handleNewMessage);

参考:https : //dev.to/luistak/cross-micro-frontends-communication-30m3#windowed-observable

- 调度/捕获自定义浏览器事件 请记住,自定义事件可以具有允许传递信息的“详细信息”

//MF1 
const customEvent = new CustomEvent('message', { detail: input.value });
window.dispatchEvent(customEvent)

//MF2 
const handleNewMessage = (event) => {
setMessages((currentMessages) => currentMessages.concat(event.detail));
};
    
window.addEventListener('message', handleNewMessage);

这种方法有一个重要的问题,它只适用于“已调度的新事件”,因此如果您目前没有捕获事件,则可以读取状态。

参考:https : //dev.to/luistak/cross-micro-frontends-communication-30m3#custom-events

在这两种实现中,使用良好的命名约定将有助于保持秩序。