Javascript 在多个上下文之间传递数据

Javascript 在多个上下文之间传递数据,javascript,reactjs,react-context,Javascript,Reactjs,React Context,在过去的几天里,我一直在修补React上下文API,将其作为一个小型宠物项目制作一个小型“CMS”。然而,我遇到了一个有趣的问题,我一直在思考这个问题,但实际上我可能想得太多了,我很高兴收到任何提示,因为我在谷歌上没有找到类似的东西,只有基本的“入门”文章 因此,假设我们有以下数据模型: 文章 类别 图像 我已经为每一项都制作了一对提供者-消费者,例如: const Context = React.createContext(); class ArticleProvider extends

在过去的几天里,我一直在修补React上下文API,将其作为一个小型宠物项目制作一个小型“CMS”。然而,我遇到了一个有趣的问题,我一直在思考这个问题,但实际上我可能想得太多了,我很高兴收到任何提示,因为我在谷歌上没有找到类似的东西,只有基本的“入门”文章

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

  • 文章
  • 类别
  • 图像
我已经为每一项都制作了一对提供者-消费者,例如:

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>
);
const Context=React.createContext();
类ArticleProvider扩展了React.Component{
this.state={articles:[]};
render(){
{this.props.children}
}
}
const ArticleConsumer=(道具)=>(
{props.children}
);
它们当然比这更丰满,但它们都有相同的结构。 现在的问题是,当你编辑一篇文章时,你可以选择一个类别和一幅图片

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

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

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

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

{(文章)=>
{(类别)=>
{(媒体)=>}
}
}
然而,我无法摆脱这样一种感觉:这是非常繁忙的,可能不是最好的方式

有什么办法可以改进吗?如果这还不够,请询问,我会将其余的代码发布到粘贴箱或其他地方

感谢您提到需要多个上下文的用例。他们说

如果两个或多个上下文值经常一起使用,您可能需要考虑创建自己的渲染PROP组件,这两个组件都提供.

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

<CombinedContextsConsumer render={({context1, context2}) => (
    <div>{context1.value}</div>
    <div>{context2.value}</div>
)}/>
(
{context1.value}
{context2.value}
)}/>
CombinedContextsConsumer看起来像:

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

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

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


问题是,我真的不能把它们放得更高,这里只有元素,然后是react init调用。另外,我想这就是我现在正在做的。你不希望提供程序出现在这个可重用的组件中,因为这样每次使用上下文时,上下文都会被重置。如果这些是全球级别的提供商,它们应该在你的应用程序的顶部。是的,我知道,它们会被卸载,然后再重新装载。如果我离开,我真的不介意在这种情况下,但如果我要存储登录的用户,我必须将其移动到尽可能高的位置。@user2941726我在回答中阐明了为什么我们不希望提供程序位于可重用组件中。即使在这种特殊情况下,它起作用,但这不是正确的做法。如果每个消费者创建自己的上下文,那么为什么要使用上下文呢?只需使用state.Fair point的常规组件。还可以避免一次又一次地复制和粘贴提供程序。