• React中setState


    mountComponent 本质上是通过 递归渲染 内容的,由于递归的特性,父组件的 componentWillMount 一定在其子组件的 componentWillMount 之前调用,而父组件的 componentDidMount 肯定在其子组件的 componentDidMount 之后调用。

    若使用 this.state.xxx 赋值更新状态,的确能够改变状态,但是无意义,也不会触发重新渲染。
    因为,this.state 只是一个对象,单纯去修改一个对象的值无意义,去驱动 UI 的更新才是有意义的。
    而 setState 方法被调用时,能驱动组件的更新过程,引发 shouldComponentUpdate、componentWillUpdate、 reader、 componentDidUpdate 等一系列方法调用,完成 UI 更新。

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8" />
        <title>React中setState</title>
        <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.15.0/babel.min.js"></script>
      </head>
      <body>
        <div id="root"></div>
        <script type="text/babel">
          class App extends React.Component {
            constructor(props) {
                super(props);
                this.state = {
                    count: 0
                    
                };
            }
            componentWillMount() {
                let me = this;
                me.setState({
                    count: me.state.count + 2
                });
                me.setState({
                    count: me.state.count + 1
                });
            }
            componentDidMount() {
                let me = this;
                me.setState({
                    count: me.state.count + 2
                });
                me.setState({
                    count: me.state.count + 1
                });
            }
    
            onClick() {
                let me = this;
                me.setState({
                    count: me.state.count + 1
                });
                me.setState({
                    count: me.state.count + 1
                });
    
                setTimeout(() => {
                    me.setState({
                        count: me.state.count + 1
                    });
                    me.setState({
                        count: me.state.count + 1
                    });
                }, 1000);            
            }
    
            render() {
                console.log(this.state.count);
                return (
                    <div>
                        <h1>{this.state.count}</h1>
                        <input type="button" value="点击我" onClick={this.onClick.bind(this)} /><br />
                        <br />
                    </div>
                )
            }
          }
     
          ReactDOM.render(
            <App />,
            document.getElementById('root')
          );
        </script>
      </body>
    </html>
    1. willmount中的setState会合并成一次执行,count只会保留最后一次的设置,前面的放弃,所以willmount之后是1,并不是3;并且在render之前执行,不会引起新的render
    2. render之后执行didMount,setState做同样的处理,这是count2,并且引起新的render
    3. 点击按钮,setState做同样处理,count3,引起新的render

    备注:

    定时器中的setState没走react的事物机制,执行时批量更新没被设置true,所以每次都直接render了。

    在按钮原生事件中定义的setState,和定时器效果一样,每次setState都会引起新的render

    因为setState并不会立刻修改this.state的值,所以下面的code可能产生很不直观的结果。

    function incrementMultiple() {
      this.setState({count: this.state.count + 1});
      this.setState({count: this.state.count + 1});
      this.setState({count: this.state.count + 1});
    }

    直观上来看,当上面的incrementMultiple函数被调用时,组件状态的count值被增加了3次,每次增加1,那最后count被增加了3,但是,实际上的结果只给state增加了1。

    原因并不复杂,就是因为调用this.setState时,并没有立即更改this.state,所以this.setState只是在反复设置同一个值而已,上面的code等同下面这样。

    function incrementMultiple() {
      const currentCount = this.state.count;
      this.setState({count: currentCount + 1});
      this.setState({count: currentCount + 1});
      this.setState({count: currentCount + 1});
    }

    currentCount就是一个快照结果,重复地给count设置同一个值,不要说重复3次,哪怕重复一万次,得到的结果也只是增加1而已。

  • 相关阅读:
    python报错: invalid syntax
    python报错:not supported between instances of 'str' and 'int'
    python类型检查和类型转换
    python的input()函数
    为什么双击打开py文件时窗口瞬间关闭了?
    python条件判断语句
    python运算符的优先级
    JDK1.8 新特性(全)
    mysql事务详解
    Java判断指定日期是否为工作日
  • 原文地址:https://www.cnblogs.com/xutongbao/p/10003201.html
Copyright © 2020-2023  润新知