反应事件层次结构问题

Posted

技术标签:

【中文标题】反应事件层次结构问题【英文标题】:React event hierarchy issue 【发布时间】:2016-03-29 14:35:36 【问题描述】:

在深节点中处理状态更改的最佳方法是什么,也需要由父节点处理。这是我的情况:

<Table>
  <Row prop=user1>
    <Column prop=user1_col1 />
    <Column prop=user1_col2 />
  </Row>
  <Row prop=user2>
    <Column prop=user2_col1 />
    <Column prop=user2_col2 />
  </Row>
  <TableFooter>
    <FooterColumn prop=sum1 />
    <FooterColumn prop=sum2 />
  </TableFooter>
</Table>

每当有人更改列属性中的任何内容时,我只需在该列组件中维护此值的状态。但是,我现在想要在 FooterColumn 组件中对这些值进行总和。实现这一目标的最佳方法是什么?

如果我要传递状态更改,我必须将状态保存在多个位置,然后再传递下去,这是很多乏味的工作。最好使用 EventEmitters 还是我错过了什么?

【问题讨论】:

【参考方案1】:

所以,你只需要跟踪父组件中的状态,并与子组件共享状态更新功能:

var Parent = React.createClass(
  getInitialState: function() 
    return 
      users: [
        name: 'Matt', values: [1, 2],
        name: 'user517153', values: [4, 5]
      ]
    ;
  ,
  updateValue: function(rowId, colId, newValue) 
    var newUsersState = this.state;
    newUsersState.users[rowId].values[colId] = newValue;
    this.setState(users: newUsersState);
  ,
  render: function() 
    var rows = this.state.users.map(function(user, r) 
      var cols = user.values.map(function(value, c) 
        return (
          <Column key=c prop=value rowId=r colId=c onChange=this.updateValue/>
        );
      );

      return (
        <Row key=r prop=user>
          cols
        </Row>
      );
    );

    // Yes, it could be more efficient if you did it all in one map/forEach - doing this in a second one for clarity
    var footerCols = this.state.users.map(function(user) 
      var sum = 0;
      user.values.forEach(function(value)  sum+= value; );
      return (
        <FooterColumn prop=sum />
      );
    );

    return (
      <Table>
        rows
        <TableFooter>
          footerCols
        </TableFooter>
      </Table>
    );
  
);

在您的 Column 课程中,您只需要以下内容:

var Column = React.createClass(
  onChange: function(event) 
    var props = this.props;

    var newValue = event.target.value; // Get the new value somehow - this is just an example
    props.onChange(props.rowId, props.coldId, newValue);
  ,
  render: function() 
    var props = this.props;

    return (
      <td onChange=this.onChnage>props.prop</td>
    );
  
);

希望这是有道理的。

【讨论】:

我支持这个。您应该努力将所有应用程序逻辑保留在最顶层的组件中,并让嵌套组件仅呈现其属性并在其中发生某些事情时触发事件,以便父级可以通过回调响应更改。 谢谢!但问题是,我中间还有一个 Row 组件,这意味着将其传递 2 次。如果我应该创建另一个子组件,它将是 3 次,这些看起来真的很乏味。这是不是应该已经使用 Flux 之类的东西了? 所以,首先,在上面使用的情况下,Row 实际上并不是Column 的父级,所以Row 不需要知道任何关于Column 的props .在 React 中,如果该组件直接呈现它的子组件,则该组件是另一个组件的父组件。因此,您可以拥有一个名为 DivMaker 的组件,其中包含 100 个嵌套 div,但所有这些 div 的父级都是 DivMaker,无论它们的嵌套深度如何。 第二个问题更有趣。是的,最终它变得难以管理。 Flux 是一个不错的选择(我更喜欢 Reflux)。还请查看 React 的 context 功能,该功能专门用于减轻必须处理通过大型组件树传递道具的问题。

以上是关于反应事件层次结构问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Qt 层次结构的根小部件中获取鼠标按下事件

iOS10 UI教程层次结构的事件

具有层次结构的 Telerik radgrid 不在 OnHierarchyExpanding 事件上运行客户端 javascript

C ++中模板类型中的类层次结构

子部件是不是应该处理自己的事件?

反应:HTML 表单应该是受控组件还是不受控组件?