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
方法只能用于真正的全局数据。如果您的数据属于任何其他类别,那么您应该执行以下操作:
我将在下面留下我对这个答案的原始编辑,以了解一些历史。
旧答案:
到目前为止,我为此找到的最佳答案是这 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 - 如何将“全局”数据传递给深度嵌套的子组件?的主要内容,如果未能解决你的问题,请参考以下文章
如何将数据传递给BottomSheetDialogFragment [重复]