【问题标题】:Passing messages between components in React.js在 React.js 中的组件之间传递消息
【发布时间】:2017-05-30 14:12:11
【问题描述】:

我对 React.js 组件之间的通信有一些疑问。这是在不使用 redux 的情况下。这是我的组件层次结构的样子。

       App
      /  \
     /    \
    |      |
    ▼      ▼
 Board   Dashboard
   |
   ▼ 
 Cell

以下是我用于组件通信的一些假设/模式。

  1. 如果我们需要将消息从父组件传递给子组件 我们使用道具来做到这一点的组件。例如,在创建一个 板我们传递行,列作为道具。

    <Board rows={5} cols={5} />
    
  2. 如果我们需要将消息从子组件传递给父组件 我们通过传递回调来完成组件。例如我们通过一个 从 Board 到 Cell 的 play() 回调。在 Cell 中,我们设置 onClick 处理程序作为传递的回调,即 play()。

    <Cell onClick={this.props.play(this.props.id)} />
    
  3. 我有一个悬而未决的问题是如何在兄弟姐妹之间传递消息 组件(例如仪表板到单元格)。一个用例是重置我的 仪表板组件中的重置按钮时的板组件 点击。这是仪表板中的重置按钮的外观。我的 问题是一旦重置消息到达 App 组件,什么是 将其传递给董事会的最佳做法?

    <input type="button" value="reset" onClick={this.props.reset} />
    

如果能获得关于 1 和 2 的一些反馈,那就太好了。另外,3 的最佳做法。

【问题讨论】:

  • 1 & 2 是处理该用例的正确方法。至于 3,如果组件是兄弟,您可以使用来自父级的回调(请参阅andrewhfarmer.com/component-communication/#5-parent-component)如果它们不是兄弟,则有一个很好的迹象,您应该将变量移动到由 redux 或其他类似管理的共享状态状态管理者。
  • @GiacomoCosimato 我真的很喜欢那个链接。谢谢...

标签: javascript reactjs


【解决方案1】:

Redux

这正是 Redux 如此酷的原因。如果你使用 Redux,那么所有这些组件都有一个共同点;他们都在从应用程序状态读取它们的值。我将使用的流程如下:

  1. 用户点击仪表板组件中的重置按钮

  2. 与该点击关联的函数只做一件事。调度“RESET_BOARD”操作

  3. 在 reducer 中,RESET_BOARD 操作会重置板的状态。

  4. 当重新渲染发生时,board 是传入 props 的,和之前一样,只传入空状态。

没有 Redux

如果您手头没有 redux,那么来自父级的回调方法是明智的选择。如果您在 App 组件中维护状态,则应用程序会重置其状态并手动触发重新渲染。这将导致 Board 使用不同的道具重新渲染。

【讨论】:

  • Redux 很酷,但是如果应用程序变得更大并且您并不总是希望所有信息流过整个虚拟 DOM 结构,您总是可以实现或使用某种其他类型的全局事件系统。
  • @Tommos : 你有理由.. 我也讨厌 redux .. 这就是为什么我所有的 react 项目都是在没有 React 的情况下完成的。 >....在需要的时候,组件之间的顺畅通信就足够了:
  • @Tommos 如果您担心的是性能,Redux 非常快,但我很欣赏不同的用例等等!我是 Redux 的忠实粉丝,但主要是因为我倾向于更多地考虑可维护性和可扩展性,而这正是 Redux 非常出色的地方。
  • redux 是一个全局和本地状态管理。发送消息可能有其他目的,例如要求所有订阅者执行命令。我认为我们不仅限于 redux,任何具有发布者-订阅者模式的库都可以在这类场景中使用。一个简单的例子在这里:davidwalsh.name/pubsub-javascript
【解决方案2】:

而且,也是限制;两个组件之间的通信在 3 种情况下受到限制:

  1. 父更新子:

  2. 子更新父:

  3. 兄弟姐妹(兄弟)互相更新(兄弟)


现在让我们找到您的问题.. 你的问题是关于第三种情况:

主要思想是让祖父母(App)作为代理传输通信。


               App
               /  \
              /    \
             |      |
             ▼      ▼
          Board   Dashboard
            |
            ▼ 
          Cell

仪表板.js

reset(event) {
  //.... local calls (concerning Dashboard or its children )
 // then , external calls (concerning outside Dashboard)
 if(this.props.onReset) this.props.onReset(event);
}

<input type="button" value="reset" onClick={this.reset} />

App.js([Dashboard, Board&gt;Cell] 之间的 1ˢᵗ 祖父母):

onDashboardReset(event) {
  this.setState({dashboardIsReset: true})
}

<Dashboard   onReset={this.onDashboardReset} />
<Board   dashboardIsReset={this.state.dashboardIsReset} />

Board.js:

   // ... has props  `dashboardIsReset` and forward it to its children (`Cell`) if needed

【讨论】:

    最近更新 更多