ReactJS - 如何将“全局”数据传递给深层嵌套的子组件?

时间:2014-09-30 11:56:10

标签: javascript facebook reactjs

人们通常如何在React应用程序中获取“全局”数据?

例如,假设用户登录我的应用后,我有以下数据。

user: {
  email: 'test@user.com',
  name: 'John Doe'
}

这是我的应用程序中几乎所有组件可能想知道的数据 - 因此它可以在登录或注销状态下呈现,或者如果已登录则可能显示用户电子邮件地址。

根据我的理解,在子组件中访问此数据的React方法是为顶级组件拥有数据,并使用属性将其传递给子组件,例如:

<App>
  <Page1/>
  <Page2>
    <Widget1/>
    <Widget2 user={user}/>
  </Page2>
</App>

但这对我来说似乎很笨拙,因为这意味着我必须通过每个复合材料传递数据,只是为了将它传递给需要它的孩子。

是否存在管理此类数据的React方法?

注意:这个例子非常简单 - 我喜欢将意图包装成复合材料,因此我认为可以根据需要彻底改变整个UI功能的实现细节。

编辑:我知道默认情况下,calling setState on my top level component would cause all child components to be re-rendered以及每个子组件中我可以使用我喜欢的任何数据进行渲染(例如全局数据,而不仅仅是状态或道具) )。但是,人们如何选择仅通知某些子组件应该呈现它们?

5 个答案:

答案 0 :(得分:17)

由于我最初回答了这个问题,因此我很清楚React本身并不支持&#34; global&#34;在任何意义上的数据 - 它真正意味着管理用户界面和它。您的应用数据需要存在于其他地方。话虽如此,它现在支持访问全球context数据as detailed in this other answer on this page。对于那些感兴趣的人,以及Unstated context api如何进化,这个回购(here's a good article by Kent Dodds)应该以更好的方式包裹context,现在正式React支持。

context方法只应用于真正的全球数据。如果您的数据属于任何其他类别,那么您应该执行以下操作:

  • Facebook自己使用自己的Flux库解决了这个问题。
  • MobxRedux与Flux类似,但似乎有更受欢迎的吸引力。他们做同样的事情,但是更清洁,更直观。

对于某些历史记录,我将原始修改留在下面的答案中。

OLD ANSWER:

<小时/> 到目前为止我找到的最好的答案是这2个React mixins,我还没有机会尝试,但听起来他们会解决这个问题:

https://github.com/dustingetz/react-cursor

和这个类似的库:

https://github.com/mquan/cortex

主要注意:我认为这是Facebook's Flux的工作,或类似的东西(以上是)。当数据流变得过于复杂时,需要另一种机制来在回调之外的组件之间进行通信,并且Flux和它的克隆似乎就是它......

答案 1 :(得分:8)

使用React Context Property这专门用于将全局数据集传递到链中而不显式转发它们。它确实使组件生命周期功能复杂化,并注意我链接的页面上提供的注意事项。

答案 2 :(得分:2)

您可以使用React Context API将全局数据向下传递到深度嵌套的子组件。 Kent C. Dodds 在媒介React’s ⚛️ new Context API上写了一篇广泛的文章。它将有助于更好地了解如何使用API​​。

答案 3 :(得分:1)

通过使用{... restOfProps}渲染所有孩子,只是将数据一直传递到组件链中会出现什么问题?

render(){
  const {propIKnowAbout1, propIKnowAbout2, ...restOfProps} = this.props;
  return <ChildComponent foo={propIKnowAbout1} bar={propIKnowAbout2} {...restOfProps}/>
}

答案 4 :(得分:1)

有Reactn https://www.npmjs.com/package/reactn
您可以使用this.global和this.setGlobal来获取和设置全局状态,就像使用本地状态一样。
为此,您只需要
import React from 'reactn';