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

Posted

技术标签:

【中文标题】ReactJS - 如何将“全局”数据传递给深度嵌套的子组件?【英文标题】:ReactJS - how to pass "global" data to deeply nested child components? 【发布时间】:2014-11-25 01:06:21 【问题描述】:

人们通常如何在 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,并且在每个子组件中我可以使用我喜欢的任何数据(例如全局数据,而不仅仅是状态或道具)进行渲染。但是人们如何选择只通知某些子组件它们应该被渲染呢?

【问题讨论】:

很多人(包括我自己)使用 Backbone 来处理 React 中的数据,然后在模型发生变化时触发重新渲染。或者,如果您愿意,您可以使用全局对象。 React 不自己处理数据,它只是提供重新渲染应用程序的方法。 感谢您的反馈!所以你只是在你的“主”组件上调用setState,然后让 React 重新渲染所有东西,不管它的状态是否改变了?这当然有效,但渲染不友好 (***.com/a/24719289/26510) 我们在主干处理程序的顶部组件上使用this.forceUpdate()。我相信这是合适的方法,但您会在此处找到更多替代方案和有关利弊的信息:***.com/questions/21709905/… 很有趣......绝对是一本好书......听起来它仍然会导致渲染发生,但如果渲染结果是相同的 html,则不会进行真正的 DOM 更改......很好要知道! 【参考方案1】:

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

【讨论】:

【参考方案2】:

自从我最初回答这个问题以来,我发现 React 本身不支持任何意义上的“全局”数据——它真正的目的是管理 UI,仅此而已。您的应用程序的数据需要保存在其他地方。话虽如此,它现在确实支持访问全局context 数据as detailed in this other answer on this page。这个 repo (Unstated) 应该以更好的方式总结了 context,对于那些感兴趣的人,here's a good article by Kent Dodds 是关于 context api 是如何演变的,现在在 React 中得到正式支持。

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

Facebook 自己使用自己的Flux 库解决了这个问题。 Mobx 和 Redux 与 Flux 类似,但似乎更受欢迎。他们做同样的事情,但以一种更简洁、更直观的方式。

我将在下面留下我对这个答案的原始编辑,以了解一些历史。

旧答案:


到目前为止,我为此找到的最佳答案是这 2 个 React mixin,我还没有机会尝试,但听起来他们会解决这个问题:

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

还有这个类似的库:

https://github.com/mquan/cortex

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

【讨论】:

很高兴知道:指向“Kent Dodds 的好文章”的链接似乎需要多层注册和注册,但只需向下滚动首屏即可绕过所有这些。 好点子 - 我刚刚将链接更改为来自 Kent Dodds 的更新文章,该文章直接进入他的网站。【参考方案3】:

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

【讨论】:

【参考方案4】:

通过使用 ...restOfProps 渲染所有子级来将数据一直传递到组件链有什么问题?

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

【讨论】:

【参考方案5】:

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

【讨论】:

以上是关于ReactJS - 如何将“全局”数据传递给深度嵌套的子组件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用ts将数据传递给vue3中的多深度子组件

如何将数据传递给BottomSheetDialogFragment [重复]

如何通过数组将数据传递给表格视图?

将自定义数据传递给 React 中的 PrivateRoute 组件

将数据传递给服务器显示未定义

如何将变量数据传递给 createFragementContainer