当调用setState()函数时会发生什么?

21

setState()函数是做什么的?它只会运行render()函数吗?


2
这里没有有用的内容吗?https://facebook.github.io/react/docs/react-component.html#setstate - mplungjan
它执行了许多来自react-dom的函数,这些函数实际上进行了差异化和DOM更新(如果需要)。 - marzelin
我只看到关于生命周期状态的答案,但没有关于setState()用途的实际答案。这是你想要的吗?还是你实际上想了解生命周期? - paddotk
@poepje,我也在答案中添加了解释,以防OP想知道。 - Shubham Khatri
@ShubhamKhatri 很棒! - paddotk
4个回答

30

setState()函数会运行什么?它只运行render()吗?

不是的,setState不仅调用render()函数,而且在setState之后,以下生命周期函数将按顺序运行,具体取决于shouldComponentUpdate返回的结果。

如果shouldComponentUpdate返回true(默认为true)。

1. shouldComponentUpdate
2. componentWillUpdate
3. render()
4. componentDidUpdate

如果您有自定义实现,shouldComponentUpdate返回false
1. shouldComponentUpdate

关于setState,还有一件事需要知道,它只会触发当前组件及其所有子组件的重新渲染(假设没有任何子组件实现shouldComponentUpdate),它不会触发父组件的重新渲染,因此父组件不会进行协调,而仅对自身和其子组件进行协调。

下面是一个调用setState时发生的DEMO。

class App extends React.Component {
    state = {
      count: 0
    }
    componentWillReceiveProps(nextProps) {
       console.log('componentWillReceiveProps parent');
    }
    shouldComponentUpdate() {
      console.log('shouldComponentUpdate parent');
      return true;
    }
    componentWillUpdate() {
      console.log('componentWillUpdate parent');
    }
    render() {
      console.log('render parent')
      return (
        <div>
            <Child count = {this.state.count}/>
            <button onClick={() => {
            console.log('callingsetState');this.setState((prevState) => ({count: prevState.count + 1}))}} >Increase</button>
        </div>
      )
    }
    componentDidUpdate() {
      console.log('componentDidUpdate parent')
    }
}
class Child extends React.Component {
    
    componentWillMount() {
      console.log('componentWillMount child');
    }
    componentDidMount() {
      console.log('componentDidMount child');
    }
    componentWillReceiveProps(nextProps) {
       console.log('componentWillReceiveProps child');
    }
    shouldComponentUpdate() {
      console.log('shouldComponentUpdate child');
      return true;
    }
    componentWillUpdate() {
      console.log('componentWillUpdate child');
    }
    render() {
      console.log('child')
      return (
        <div>
            <div>{this.props.count}</div>
        </div>
      )
    }
    componentDidUpdate() {
      console.log('componentDidUpdate child')
    }
}


ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

为了回答@poepje在您的问题中提出的疑问,需要添加解释。

setState是什么?

setState()将更改排队到组件状态,并告诉React需要使用更新后的状态重新渲染此组件及其子组件。这是您用于响应事件处理程序和服务器响应来更新用户界面的主要方法。

React在此功能文档中有很好的说明。

您也可以查看以下答案,了解setState的工作原理:

setState不会立即更新状态


13

setState() 将按照以下顺序运行函数:

shouldComponentUpdate()

componentWillUpdate()

render()

componentDidUpdate()

如果您的组件正在接收 props,则将使用上述函数运行 componentWillRecieveProps() 函数。


4
当调用setState时,React首先要做的是将您传递给setState的对象合并到组件的当前状态中。这将启动一个称为“协调”的过程。协调的最终目标是以尽可能高效的方式根据此新状态更新UI。
为了做到这一点,React将构建一个新的React元素树(您可以将其视为UI的对象表示)。一旦拥有了这棵树,为了确定UI如何响应新状态而更改,React将比较这个新树和之前的元素树。
通过这样做,React将知道发生的确切变化,并且通过准确知道发生的变化,将能够最小化其对UI的足迹,并仅在绝对必要时进行更新。
setState()将按照以下顺序运行函数:
shouldComponentUpdate()

componentWillUpdate()

render()

componentDidUpdate()

如果你的组件接收了props,它将会运行上述函数中的componentWillReceiveProps()函数。

0

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