【问题标题】:Passing data between multiple Contexts在多个上下文之间传递数据
【发布时间】:2018-12-31 07:02:19
【问题描述】:

过去几天我一直在修改 React Context API,将它作为一个小型宠物项目制作了一个小型“CMS”。但是我遇到了一个有趣的问题,我一直在考虑它,但实际上我可能想多了,我很乐意收到任何指示,因为我在 Google 中没有找到类似的东西,只有基本的“入门”文章。

假设我们有以下数据模型:

  • 文章
  • 类别
  • 图片

我已经为这些中的每一个创建了一个提供者-消费者对,例如:

const Context = React.createContext();

class ArticleProvider extends React.Component {
    this.state = { articles : [] };

    render() {
        <Context.Provider value={ this.state }>
            {this.props.children}
        </Context.Provider>
    }
}

const ArticleConsumer = (props) => (
    <Context.Consumer>
        { props.children }
    </Context.Consumer>
);

它们当然比这更充实,但它们都具有相同的结构。 现在我遇到的问题是,当你编辑一篇文章时,你可以选择一个类别和一张图片。

为了解决这个问题,我制作了名为 ArticleForm 的组件。这个表单是一个简单的组件,仅以 props 为参数。

我还有另一个名为 MediaGrid 的组件,用于在单独的页面上显示和上传图像。

所以为了确保 ArticleForm 可以做我想做的所有事情,我制作了以下名为 ArticleFormContainer 的组件,我的想法是我可以重用 MediaGrid 组件:

<ArticleProvider { ...props }>
  <CategoryProvider>
    <MediaProvider>
      <ArticleConsumer>
        { (article) =>
          <CategoryConsumer>
            { (category) =>
              <MediaConsumer>
                { (media) => <ArticleForm { ...article } { ...category } { ...media } /> }
              </MediaConsumer>
            }
          </CategoryConsumer>
         }
       </ArticleConsumer>
     </MediaProvider>
   </CategoryProvider>
</ArticleProvider>

然而,我无法摆脱这种非常忙碌的感觉,而且可能不是最好的方式。

任何想法如何改善这一点?如果这还不够信息,请询问,我会将其余代码发布到 Pastebin 或其他东西中。

谢谢

【问题讨论】:

    标签: javascript reactjs react-context


    【解决方案1】:

    react docs 提到了需要多个上下文的用例。他们说

    如果两个或多个上下文值经常一起使用,您可能需要考虑创建自己的渲染道具组件来提供两者。

    因此,基本理念是您可以在整个应用中使用组合上下文,例如:

    <CombinedContextsConsumer render={({context1, context2}) => (
        <div>{context1.value}</div>
        <div>{context2.value}</div>
    )}/>
    

    使用 CombinedContextsConsumer 看起来像:

    <Context1.Consumer>
        {context1 => (
            <Context2.Consumer>
                {context2 => (
                    {props.render({context1, context2})}
                )}
            </Context2.Consumer>
        )}
    </Context1.Consumer>
    

    您不希望此可重用组件中的提供程序。这将导致上下文数据在每次使用时都被重置。这也意味着消费者不会在彼此之间共享数据,因为他们每个人都有他们自己的上下文副本。如果这些是全局上下文,则提供程序应该在树中更高的应用程序级别。

    npm 上有几个包可以让你更轻松地完成这项工作,但我从来没有亲身体验过它们。这个看起来很有趣:

    https://www.npmjs.com/package/react-compose-context-consumers

    【讨论】:

    • 问题是,我真的不能把这些放在更高的位置,那里只有 元素,然后是 react init 调用。另外,我认为这就是我现在正在做的事情。
    • 好吧,您不希望在这个可重用组件中提供提供程序,因为这样每次使用时上下文都会被重置。如果这些是全局级别的提供程序,它们应该位于您应用的顶部。
    • 是的,我知道,如果我离开,它们会被卸载然后重新安装,在这种情况下我并不介意,但如果我要存储登录用户,我将不得不移动尽可能高。
    • @user2941726 我在回答中澄清了为什么我们不希望将提供程序放在可重用组件中。即使在这种特定情况下它有效,这也不是正确的做法。如果每个消费者都创建自己的上下文,那么为什么还要使用上下文呢?只需使用带有状态的常规组件即可。
    • 公平点。还省去了一次又一次地复制和粘贴提供者的麻烦。
    猜你喜欢
    • 2017-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-05
    • 2019-04-24
    • 1970-01-01
    • 1970-01-01
    • 2018-04-16
    相关资源
    最近更新 更多