简体   繁体   English

使用 React Context 与 Event Bus 连接深度嵌套的独立组件

[英]Connect deeply nested independent components using React Context vs Event Bus

So I have a few deeply nested independent components that need to communicate with each other.所以我有几个深度嵌套的独立组件需要相互通信。 For example I have a news overview which contains a feed, which can be collapsed/hidden from the navigation.例如,我有一个新闻概览,其中包含一个提要,可以在导航中折叠/隐藏。 The navigation is at a completely different place within the DOM than the news feed, hence passing props isn't really possible.导航在 DOM 中与新闻提要完全不同的地方,因此传递道具是不可能的。

Since I have these kind of dependencies with multiple components, I have implemented a React Context for now to handle these states.由于我对多个组件有这种依赖关系,因此我现在实现了一个 React Context 来处理这些状态。 To reach each and every component the context wraps the whole app.为了访问每个组件,上下文包装了整个应用程序。

Is this a good practice or should I go for a kind of EventBus instead?这是一个很好的做法还是我应该改用一种EventBus

const eventBus = {
  on(event, callback) {
    // ...
  },
  dispatch(event, data) {
    // ...
  },
  remove(event, callback) {
    // ...
  },
};

vs对比

<CustomThemeProvider>
     <Component {...pageProps} /> // app
</CustomThemeProvider>

What's the best practice here?这里的最佳做法是什么?

Consider this code fragment:考虑这个代码片段:

      //providers
      <AccountContext.Provider value={{...this.state, onAccountLastVisited}}>
          ...
          <VersionContext.Provider value={{...this.state, onUpdateVersion}}>
              ...
              <TrackingContext.Provider value={{...this.state, onCodeTracking}}>
                  ...
                  <NotificationContext.Provider value={{...this.state, onSendNotification}}>
      //consumers
      <AccountContext.Consumer>{accContext=> {
          ...
          <VersionContext.Consumer>{verContext=> {
              ...
              <TrackingContext.Consumer>{trkContext=> {
                  ...
                  <NotificationContext.Consumer>{nftContext=> {
                      const {onAccountLastVisited} = accContext;
                      const {onUpdateVersion     } = verContext;
                      const {onCodeTracking      } = trkContext;
                      const {onSendNotification  } = nftContext;
                      ...
                      ... onSubmit={()=> {
                              onAccountLastVisited(eventData);
                              onUpdateVersion     (eventData);
                              onCodeTracking      (eventData);
                              onSendNotification  (eventData);
                          };}
  1. That looks ugly asf.这看起来很丑陋。

  2. Tightly coupled with the knowledge of components outside everywhere.外面到处都是组件的知识紧耦合。

  3. Component is polluted and you have to come back to edit this thing whenever you come up with a new context provider/consumer.组件被污染了,每当你想出一个新的上下文提供者/消费者时,你必须回来编辑这个东西。

Don't know about you, but it hurts my eyes.不了解你,但它让我的眼睛受伤。

Now on the other hand:现在另一方面:

    //listener
    EventBus.on('TaskForm.submitClick', onAccountLastVisited);
    ...
    //caller
    ... onSubmit={()=> {
        EventBus.dispatch('TaskForm.submitClick', eventData);
    }

That's it.而已。

  1. Now this component knows nothing about its parents or providers, completely decoupled.现在这个组件对其父级或提供者一无所知,完全解耦。

  2. Very clean.很干净。 Any context module can listen to the event and do the context update.任何上下文模块都可以监听事件并进行上下文更新。

  3. Doesn't matter if your component event is travelling up, down, or side ways.无论您的组件事件是向上、向下还是横向移动都无关紧要。

I DO NOT see why we don't use the event bus.我不明白为什么我们不使用事件总线。 Full disclosure here, I am not a React expert.在这里完全公开,我不是 React 专家。 If anyone can give me a better reason why I should stick with the providers, I am all ears.如果有人可以给我一个更好的理由为什么我应该坚持使用提供者,我会全力以赴。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM