直接修改反应组件的状态是否可靠一致?

时间:2019-11-21 00:57:41

标签: reactjs react-state-management

浏览同事的ReactJS代码时,我注意到他们“直接修改状态”。我还使用以下代码进行了尝试:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
        <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
        <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
    </head>
    <body>

        <div id="app"></div>
        <script type="text/babel">

        class App extends React.Component {
            constructor(props) {
                super(props);
                this.state = {"message":""};
            }
            textChange(evt) {
                this.state.message = evt.currentTarget.value;
                this.setState({});
            }
            render() {
                return (
                    <div>
                        <p>{this.state.message}</p>
                        <input type="text" onChange={evt=>this.textChange(evt)} />
                    </div>
                );
            }
        }
        ReactDOM.render(<App />, document.getElementById('app'));
        </script>
    </body>
</html>

方法textChange(evt)持续可靠地更新状态。我在互联网上的一些博客中读到,我们不应该直接修改状态...我是否误解了?

还要考虑所有其他修改状态的方法:

textChange1(evt) {
    this.state.message = evt.currentTarget.value;
    this.setState(this.state);
}
textChange2(evt) {
    const state = this.state;
    state.message = evt.currentTarget.value;
    this.setState(state);
}
textChange3(evt) {
    const state = this.state;
    state.message = evt.currentTarget.value;
    this.setState({});
}
textChange4(evt) {
    this.setState({message:evt.currentTarget.value});
}
textChange5(evt) {
    let message = evt.currentTarget.value;
    this.setState({message});
}

其中哪些是在ReactJS中修改状态的惯用方式?

1 个答案:

答案 0 :(得分:1)

您是对的,因为我们永远不要直接修改状态(除非它在构造函数中)。这样做可能有效,但会导致意外的副作用。

  

在调用setState时总是创建新的对象和数组

来源:https://daveceddia.com/why-not-modify-react-state-directly/

  

不要直接从react docs本身修改状态<---

来源:https://reactjs.org/docs/state-and-lifecycle.html

在您的示例中,以下2条是修改状态的最佳/惯用方式。请注意,当您使用{}时,您正在初始化一个对象常量(即创建一个新对象),这是下面两种方法所要做的(但当然,这本身并不意味着它是正确的,因为您可以看到textChange3)。

// great
textChange4(evt) {
    this.setState({message:evt.currentTarget.value});
}
// great
textChange5(evt) {
    let message = evt.currentTarget.value; // note `let` should be `const` (style-wise) since you are not reassigning message, but otherwise this is fine!
    this.setState({message});
}

使用注释分解每种方法

// not good
textChange1(evt) {
    this.state.message = evt.currentTarget.value; // modifying original state object
    this.setState(this.state);
}
// not good
textChange2(evt) {
    const state = this.state; // this is the exact same as above,
    // except you aliased this.state as state.
    state.message = evt.currentTarget.value;
    this.setState(state);
}
// not good
textChange3(evt) {
    const state = this.state;
    state.message = evt.currentTarget.value; // same problem as above of modifiying state directly
    this.setState({}); // you might expect the state to be set to an empty object, but it's not
    // in this case it's basically a no-op because state updates are merged. see https://reactjs.org/docs/state-and-lifecycle.html
}
// great
textChange4(evt) {
    this.setState({message:evt.currentTarget.value});
}
// great
textChange5(evt) {
    let message = evt.currentTarget.value; // note `let` should be `const` (style-wise) since you are not reassigning message, but otherwise this is fine!
    this.setState({message});
}