将状态作为属性传递给子组件是一种好的实践吗?

19

我发现自己正在将状态进行归集,通常是在我知道将要重新渲染的节点上,以便更改可以传播而且状态不会到处都是。最近,我发现自己大多数时候将此组件的状态作为属性传递给其第一个子级,使用JSX 扩展属性。请明确这是我的意思:

var Child = React.createClass({
  handleClick: function(){
    this.props.owner.setState({
      count: this.props.count + 1,
    });
  },
  render: function(){
    return <div onClick={this.handleClick}>{this.props.count}</div>;
  }  
});

var Parent = React.createClass({
  getInitialState: function(){
    return {
      count: 0,
      owner: this
    };
  },
  render: function(){
    return <Child {...this.state}/>
  }
});

它有效(http://jsbin.com/xugurugebu/edit?html,js,output),您始终可以返回该组件以了解发生了什么,并尽可能使状态最小化。

因此,实际问题是,这是否是一个好的做法,为什么。

我目前能想到的缺点是,采用这种方法可能会导致每个子组件在所有者状态更改时都重新渲染,如果是这种情况,则认为上述内容适用于小型组件树。


当父组件将所有本地状态传递给子组件时,使用扩展属性并不是非常规范和易于理解的。实际上,根据组件的复杂程度,可能很难推断出正在发送什么。我还会惊讶于子组件是否真的需要父组件的所有状态。 - WiredPrairie
1
是的,这得看情况。要查看发送了什么,只需查看父级即可。我喜欢这个原因是它清楚地表明了状态从哪里来以及如何呈现。 - stringparser
如果父组件在本地定义,那么很容易解决。但是随着项目范围的扩大,一个组件被多种类型的父组件使用时,挑战可能会变得更加复杂。 - WiredPrairie
是的,对于“附近”的组件来说没问题。不过,在大型层次结构中跟踪从一个组件传播到下一个组件的道具会比从任何情况下查看该组件的this.props.owner更困难。 - stringparser
1个回答

23

是的!

应该仅在顶层元素上设置状态,这样可以确保数据只通过组件单向流动。

请记住,React 仅呈现自上次呈现以来发生更改的内容。 如果您的某些子元素未被修改,则不会重新呈现到 DOM 中。

React 在其文档中有一个名为“lifting up state” 的部分。


没错!我没有考虑到差异。所以你的意思是说,差异算法会负责理解重新渲染的含义,因此即使传播,它也只会确保重新渲染实际有变化的DOM元素。我认为,如果这个方案行得通,我会测量一些数据并进行性能检测,看看这种方法的效果如何。 - stringparser
@stringparser 正确。React使用虚拟DOM来对比任何更改。然后,只有这些更改会被渲染到真实的DOM中。在jsperf上有许多React渲染测试,例如http://jsperf.com/react-vs-pure-js/9。 - Kristian Roebuck
虽然我同意这一点,而且我经常这样做,但我发现这篇文章中的这个短语很有趣:“它是通过props从父组件传递过来的吗?如果是,那么它可能不是state。”。 - basilisk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接