在React组件中多次使用this.setState会发生什么?

时间:2022-09-08 23:47:35

I wanted to check what happens when you use this.setState multiple times (2 times for the sake of the discussion). I thought that the component will be rendered twice but apparently it's rendered only once. Another expectation I had was that maybe the second call for setState will run over the first one, but you guessed it - worked fine.

我想检查多次使用this.setState时会发生什么(为讨论起见,这是2次)。我认为该组件将呈现两次,但显然它只呈现一次。我的另一个期望是,对于setState的第二次调用可能会超过第一次,但你猜对了 - 工作正常。

Link to a JSfiddle

链接到JSfiddle

var Hello = React.createClass({
  render: function() {
    return (
      <div>
        <div>Hello {this.props.name}</div>
        <CheckBox />
      </div>
    );
  }
});

var CheckBox = React.createClass({
  getInitialState: function() {
    return {
      alex: 0
    };
  },

  handleChange: function(event) {
    this.setState({
      value: event.target.value
    });
    this.setState({
      alex: 5
    });
  },

  render: function() {
    alert('render');
    return (
      <div>
        <label htmlFor="alex">Alex</label>
        <input type="checkbox" onChange={this.handleChange} name="alex" />
        <div>{this.state.alex}</div>
      </div>
    );
  }
});

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

As you'll see, an alert that says 'render' pops up on every render.

正如您将看到的,每次渲染时都会弹出一个“渲染”警告。

Do you have an explanation for why it worked properly?

你有解释为什么它正常工作?

2 个解决方案

#1


53  

React batches state updates that occur in event handlers and lifecycle methods. Thus, if you update state multiple times in a <div onClick /> handler, React will wait for event handling to finish before re-rendering.

React批处理事件处理程序和生命周期方法中发生的状态更新。因此,如果在

处理程序中多次更新状态,React将在重新呈现之前等待事件处理完成。

To be clear, this only works in React-controlled synthetic event handlers and lifecycle methods. State updates are not batched in AJAX and setTimeout event handlers, for example.

需要说明的是,这仅适用于React控制的综合事件处理程序和生命周期方法。例如,状态更新不会在AJAX和setTimeout事件处理程序中进行批处理。

#2


2  

The setState() method does not immediately update the state of the component, it just puts the update in a queue to be processed later. React may batch multiple update requests together to make rendering more efficient. Due to this, special precautions must be made when you try to update the state based on the component's previous state.

setState()方法不会立即更新组件的状态,它只是将更新放入队列中以便稍后处理。 React可以将多个更新请求批处理在一起,以提高渲染效率。因此,当您尝试根据组件的先前状态更新状态时,必须采取特殊预防措施。

For example, the following code will only increment the state value attribute by 1 even though it was called 4 times:

例如,以下代码仅将状态值属性递增1,即使它被调用了4次:

 class Counter extends React.Component{
   constructor(props){
     super(props)
    //initial state set up
     this.state = {value:0}
   }
   componentDidMount(){
    //updating state
    this.setState({value:this.state.value+1})
    this.setState({value:this.state.value+1})
    this.setState({value:this.state.value+1})
    this.setState({value:this.state.value+1})
   }
   render(){
    return <div>Message:{this.state.message}</div>
   }
}

In order to use a state after it has been updated, do all logic in the callback argument:

为了在更新后使用状态,请执行回调参数中的所有逻辑:

//this.state.count is originally 0
this.setState({count:42}, () = {
  console.log(this.state.count)
//outputs 42
})

The setState(updater,[callback]) method can take in an updater function as its first argument to update the state based on the previous state and properties. The return value of the updater function will be shallowly merged with the previous component state. The method updates the state asynchronously, so a there is an option callback that will be called once the state has finished updating completely.

setState(updater,[callback])方法可以接受updater函数作为其第一个参数,以根据先前的状态和属性更新状态。 updater函数的返回值将与先前的组件状态浅层合并。该方法异步更新状态,因此有一个选项回调,一旦状态完全更新将被调用。

Example:

例:

this.setState((prevState, props) => { 
return {attribute:"value"}
})

Here is an example of how to update the state based on previous state:

以下是如何根据以前的状态更新状态的示例:

    class Counter extends React.Component{
      constructor(props) {
        super(props)
    //initial state set up
        this.state = {message:"initial message"}
    }
      componentDidMount() {
    //updating state
        this.setState((prevState, props) => {
          return {message: prevState.message + '!'}
        })
     }
     render(){
       return <div>Message:{this.state.message}</div>
     }
  }

#1


53  

React batches state updates that occur in event handlers and lifecycle methods. Thus, if you update state multiple times in a <div onClick /> handler, React will wait for event handling to finish before re-rendering.

React批处理事件处理程序和生命周期方法中发生的状态更新。因此,如果在

处理程序中多次更新状态,React将在重新呈现之前等待事件处理完成。

To be clear, this only works in React-controlled synthetic event handlers and lifecycle methods. State updates are not batched in AJAX and setTimeout event handlers, for example.

需要说明的是,这仅适用于React控制的综合事件处理程序和生命周期方法。例如,状态更新不会在AJAX和setTimeout事件处理程序中进行批处理。

#2


2  

The setState() method does not immediately update the state of the component, it just puts the update in a queue to be processed later. React may batch multiple update requests together to make rendering more efficient. Due to this, special precautions must be made when you try to update the state based on the component's previous state.

setState()方法不会立即更新组件的状态,它只是将更新放入队列中以便稍后处理。 React可以将多个更新请求批处理在一起,以提高渲染效率。因此,当您尝试根据组件的先前状态更新状态时,必须采取特殊预防措施。

For example, the following code will only increment the state value attribute by 1 even though it was called 4 times:

例如,以下代码仅将状态值属性递增1,即使它被调用了4次:

 class Counter extends React.Component{
   constructor(props){
     super(props)
    //initial state set up
     this.state = {value:0}
   }
   componentDidMount(){
    //updating state
    this.setState({value:this.state.value+1})
    this.setState({value:this.state.value+1})
    this.setState({value:this.state.value+1})
    this.setState({value:this.state.value+1})
   }
   render(){
    return <div>Message:{this.state.message}</div>
   }
}

In order to use a state after it has been updated, do all logic in the callback argument:

为了在更新后使用状态,请执行回调参数中的所有逻辑:

//this.state.count is originally 0
this.setState({count:42}, () = {
  console.log(this.state.count)
//outputs 42
})

The setState(updater,[callback]) method can take in an updater function as its first argument to update the state based on the previous state and properties. The return value of the updater function will be shallowly merged with the previous component state. The method updates the state asynchronously, so a there is an option callback that will be called once the state has finished updating completely.

setState(updater,[callback])方法可以接受updater函数作为其第一个参数,以根据先前的状态和属性更新状态。 updater函数的返回值将与先前的组件状态浅层合并。该方法异步更新状态,因此有一个选项回调,一旦状态完全更新将被调用。

Example:

例:

this.setState((prevState, props) => { 
return {attribute:"value"}
})

Here is an example of how to update the state based on previous state:

以下是如何根据以前的状态更新状态的示例:

    class Counter extends React.Component{
      constructor(props) {
        super(props)
    //initial state set up
        this.state = {message:"initial message"}
    }
      componentDidMount() {
    //updating state
        this.setState((prevState, props) => {
          return {message: prevState.message + '!'}
        })
     }
     render(){
       return <div>Message:{this.state.message}</div>
     }
  }