在 React 中的组件之间共享数据

Posted

技术标签:

【中文标题】在 React 中的组件之间共享数据【英文标题】:Sharing data between components in React 【发布时间】:2016-10-23 06:47:42 【问题描述】:

我正在开发一个使用 Meteor 和 React 作为视图引擎的应用程序

考虑这个图表:

React hide component from another example

当触发 C4 按钮单击事件时,我需要更改 C2 组件状态。 由于它们没有直接关系,我无法直接从 C4 访问 C2 状态。

另一个例子是从一个组件提交一个表单并获取另一个组件中声明的数据(输入字段的值)。

我知道有一些可能的技巧可以解决这个问题 (例如 Meteor Session,通过每个组件传递数据,基于通量的 Action/Dispatcher)。

React 文档推荐使用事件/订阅系统(flux 是一种可能的解决方案,但flux 远不止于此...)Communicate Between Components

Redux 是另一种可能性(我有点担心,对于大型应用程序,如果我有很多操作,combined-reducers-function 会爆炸,而且还担心缺少特定于操作的订阅系统 -据我所知,派发动作时所有的监听器都会被执行——我是 redux 的新手,也许我错了)

Flux 或 Redux 是有效的模式,可以满足比我更大的需求,我已经有了 Meteor 来完成这种工作。 我唯一需要的是访问另一个内部的组件状态...

我需要一个针对具有大量组件视图的中型/大型应用程序的可扩展解决方案

解决这个问题的“正确”方法是什么?


更新:

最近我给了 redux 一个机会,它似乎完成了工作(它真的很棒并且得到很好的支持),所以如果你处于同样的情况,请检查React + Redux: submit multi-component form

【问题讨论】:

【参考方案1】:

您可以使用任何发布/订阅事件库,然后让您的组件监听您需要的任何事件。

例如:

import React from 'react'
import 'events' from 'eventPublishSubscribeLibrary'

class Component2 extends React.Component 
  constructor (props) 
    super(props)
    this.toggleVisibility = this.toogleVisibility.bind(this)
    this.state = 
      visible = true
    
  
  componentDidMount () 
    events.subscribe('clicked-button', this.toogleVisibility)
  
  toogleVisibility () 
    this.setState(
      visible: !this.state.visible
    )
  
  render () 
    return visible && (
      <div>content</div>
    )
  


const Component4 = () => (
  <button onClick=events.publish('clicked-button')>Toggle Visibility</button>
)

您可以在 davidwalsh 的这篇文章中找到 Pub/Sub javascript Object 的简单实现。或者您可以 search in npm 获取其他库。

“正确”方式

这是我能想到的最简单的实现,对于小型项目来说,它是一个快速简单的解决方案,应该可以工作。

无论如何,只要项目稍微增长一点,您的组件之间就会开始有很多动作/反应。对于您要添加的每个新组件,跟踪所有组件之间的所有这些关系 会变得更加复杂。这是将应用程序的 global 状态存储在一个地方的方便之处,这也是 redux 所基于的 three principles 之一:单一事实来源

【讨论】:

是的,你是对的,对于大型应用程序 redux 给你更多的控制权,一个独特的全局状态可以给你一个强大的测试工具。我有点担心无法订阅特定操作的函数,但订阅是在调度程序上进行的。 ...甚至...如果单个减速器的状态变得复杂(在大型应用程序中,可能会是这样,或者您可能有很多小型减速器...)更新过程将是曲折的,状态三叶的更新将克隆整个对象子三 “我有点担心无法订阅特定操作的函数”是什么意思?使用 redux,您不必订阅任何事件。您有 容器组件,它们 连接 到 redux 状态和调度操作。此容器的任何其他子组件都只是 presentational 并且它们对 redux 一无所知。在 redux 文档中有更好的解释:Presentational and Container Components 要在大型应用程序中组织化简器,您可以将它们分成多个文件。例如:reducers/users.jsreducers/products.js 等。这总是会更容易维护遍布所有组件的大量发布/订阅。 我认为 Redux 非常适合管理应用程序状态,“small reducer”是一个很好的解决方案。【参考方案2】:

我认为现在是您为应用引入一些状态的最佳时机。试试Redux,太棒了。

【讨论】:

您是否应该解释一下您认为如何处理“另一个示例是从组件提交表单并获取在另一个组件中声明的数据(输入字段的值)。”用 redux 吗?

以上是关于在 React 中的组件之间共享数据的主要内容,如果未能解决你的问题,请参考以下文章

在没有关系的 React 组件之间共享数据?

如何使用 react-query useMutation 在多个组件之间共享数据

react js中不相关的组件之间如何共享数据?

是否可以使用 React 中的 useState() 钩子在组件之间共享状态?

React-Redux实现组件间数据共享+项目打包

React-Redux实现组件间数据共享+项目打包