状态和道具是否可变?

时间:2016-07-20 09:06:02

标签: reactjs

假设我有一个反应组件 - 一个按钮 - 当我点击它时会增加一个值。

例如

var Component = React.createClass({
    getInitialState: function() {
        return {count: 0}
    },

    increment: function() {
        this.setState({count: this.state.count + 1})
    },

    render: function() {
        return (<button onClick={this.increment}>{this.state.count}</button>);
    }
})

React.render(<Component />, document.getElementById('react-container'));

状态是可变的!

我可以用道具做类似的事情

var Component = React.createClass({
    increment: function() {
        this.setProps({count: this.props.count + 1})
    },

    render: function() {
        return (<button onClick={this.increment}>{this.props.count}</button>);
    }
})

React.render(<Component count={0}/>, document.getElementById('react-container'));

状态是可变的!

我检查过的一些资源说道具是不可改变的,但是然后去做setProps之类的事情。不同的资源互相矛盾。这使我很难掌握状态和道具之间的区别。

道具是否可变?如果没有,为什么我可以改变它们?似乎改变道具不是好习惯,这是真的吗?如果是,为什么setProps存在?

2 个答案:

答案 0 :(得分:6)

this.propsthis.state 可以进行变异,但这实际上只是JS中对象可变性的结果。

this.setState变异当前状态的断言是错误的;创建表示状态的新对象,并应用更改。

说实话,我甚至不知道setProps存在,但它听起来像是一个完整的反模式!道具的重点在于它们被传递给组件,强制执行单向数据流。如果组件可以更改自己的道具,则此流程将被破坏。

您应该真正的目标是尽可能多地将应用程序状态存储在顶层,即在商店中,而不是使用组件状态。如果所有的州都在一个地方,那么理由就更容易了。

答案 1 :(得分:5)

setProps是React早期的延续,现在已经被弃用了很长时间。你是对的,从组件中改变道具不是一个好习惯 - 把它们想象成函数的参数。而不是改变道具,你应该:

  • 使用回调道具通知家长发生了什么事情 - 家长可以改变它拥有的数据并通过道具将其传回给孩子。
  • 像在第一个示例中一样使用组件状态。

这两种解决方案的共同之处在于,单个组件拥有数据,而且这是唯一允许修改数据的组件 - 这通常被称为“单一真实来源”。以这种方式构建代码的好处在于它意味着你不会陷入意大利面条码的纠结中,试图改变一段数据。