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

问题描述 投票:0回答:5

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

javascript reactjs
5个回答
31
投票

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

No setState 不仅会调用

render()
函数,而且在
setState
之后,以下生命周期函数将根据
shouldComponentUpdate
返回的内容按顺序运行

if

shouldComponentUpdate
返回 true(默认为 true)。

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

if

shouldComponentUpdate
返回 false(如果您有自定义实现)

1. shouldComponentUpdate

关于 setState 还要了解的一点是,它只会触发当前组件及其所有子组件的重新渲染(考虑到其任何子组件都没有实现

shouldComponentUpdate
),它不会触发重新渲染父组件的,因此
reconcilation
不会发生在父组件上,而只会发生在其自身及其子组件上。

调用

setState
时会发生什么情况的演示。

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,它将运行具有上述函数的 componentWillRecieveProps() 函数。


0
投票

只是对此答案的更新: https://stackoverflow.com/a/45273993/7310034 (因为生命周期方法现已更新)

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

getDerivedStateFromProps()

shouldComponentUpdate()

render()

getSnapBeforeUpdate
(如果存在)

componentDidUpdate()

据此: http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/


0
投票

useState
函数可以内部访问其定义的顶级函数的行为。这并不神奇,只需使用
this
参考即可。

因此,通过调用

setState
函数,它会采用其更高级别的函数并使用
this
进行
DOM
比较。

创建简单示例

useState
:)

function createState(val) {
    // `this` is top level reference (App function)
    const state = {
        call: 0,
        context: this,
        value: val
    };

    var _useState = function(callback){
        
         val = state.value = callback(val);
         
         state.call++;
         console.log("call: ", state.call)

         return val
    };

    return _useState;
};

function useState(value) {
  return [
       value,
       // pass null to access parent reference (App function)
       createState.bind(null, value)()
  ]; 
}

function App() {
    
  const  [val, setVal] =  useState(10)

  console.log(setVal(v => v+3));
  console.log(setVal(v => v+3));

}

App()

© www.soinside.com 2019 - 2024. All rights reserved.