ReactJS:React中不变性助手的真实世界使用情况是什么?

时间:2015-01-19 19:30:48

标签: immutability reactjs

React的官方文件提供Immutability Helpers

这些助手的现实使用情况是什么?我想我错过了一些非常基本的东西。

3 个答案:

答案 0 :(得分:6)

React假设在状态中设置的对象是不可变的,这意味着如果要添加或删除数组中的某个元素,您应该创建一个带有添加元素的新元素,保持上一个数组不变:

var a = [1, 2, 3];
var b = React.addons.update(a, {'$push': [4] });
console.log(a); // [1, 2, 3];
console.log(b); // [1, 2, 3, 4];

通过使用不可变对象,您可以轻松检查对象的内容是否已更改:

React.createClass({
    getInitialState: function () {
        return { elements: [1, 2, 3] };
    },
    handleClick: function() {
        var newVal = this.state.elements.length + 1;
        this.setState({
            elements: React.addons.update(this.state.elements, { '$push': [ newVal ] })
        })
    },
    shouldComponentUpdate: function (nextProps, nextState) {
        return this.state.elements !== nextState.elements;
    },
    render: function () {
        return (
            <div onClick={this.handleClick}>{ this.state.elements.join(', ') }</div>
        );
    }
});

答案 1 :(得分:2)

ReactJS状态最好是不可变。这意味着,每次调用render()时,this.state都应该是一个不同的对象。即:oldState == newState为false,oldState.someProp == newState.someProp也为false。

因此,对于简单的状态对象,毫无疑问它们应该被克隆。但是,如果您的状态对象非常复杂和深入,克隆​​整个状态可能会影响性能。因此,React的不变性助手很聪明,只能克隆它认为应该克隆的对象。

当您自己克隆状态时,就是这样做的:

onTextChange: function(event) {
    let updatedState = _.extend({}, this.state); // this will CLONE the state. I'm using underscore just for simplicity.
    updatedState.text = event.text;
    this.setState(updatedState);
}

当你让React的不变性助手确定它应该实际克隆的对象时,你就是这样做的。

onTextChange: function(event) {
    let updatedState = React.addons.update(this.state, { text: {$set: event.text} });
    this.setState(updatedState);
}

state过于复杂和深刻时,上面的示例将比第一个示例更好。

答案 2 :(得分:2)

React应用程序更喜欢不变性,有两种方式(来自Facebook)支持不变性,一种是使用immutable.js这是一个完全不变的库,另一种是immutable helper,它是一个轻量级的帮助器。您只需要在一个项目中选择一个。

immutable.js的唯一缺点是它在整个应用程序中泄漏,包括商店和视图组件,例如,

// Stores
props = props.updateIn(['value', 'count'], count => count + 1);

// View Components
render: function() {
    return <div>{this.props.getIn("value", "count")}</div>;
}

如果使用immutable helper,则可以将更改操作封装在更新发生的位置(例如Stores和Redux Reducers)。因此,您的View组件可以更加可重用。

// Stores or Reducers
props = update(props, {
    value: {count: {$set: 7}}
};

// View Components can continue to use Plain Old JavaSript Object
render: function() {
    return <div>{this.props.value.count}</div>;
}