setState不会立即更新状态

我想问一下为什么在执行onclick事件时状态没有变化。我已经搜索了一段时间,我需要在构造函数中绑定onclick函数,但状态仍未更新。这是我的代码:

import React from 'react';

import Grid from 'react-bootstrap/lib/Grid';
import Row from 'react-bootstrap/lib/Row';
import Col from 'react-bootstrap/lib/Col';

import BoardAddModal from 'components/board/BoardAddModal.jsx';

import style from 'styles/boarditem.css';

class BoardAdd extends React.Component {

    constructor(props){
        super(props);

        this.state = {
            boardAddModalShow: false
        }

        this.openAddBoardModal = this.openAddBoardModal.bind(this);
    }
    openAddBoardModal(){
        this.setState({ boardAddModalShow: true });
// After setting a new state it still return a false value
        console.log(this.state.boardAddModalShow);

    }

    render() {

        return (
            <Col lg={3}>
                <a href="javascript:;" className={style.boardItemAdd} onClick={this.openAddBoardModal}>
                    <div className={[style.boardItemContainer,style.boardItemGray].join(' ')}>
                        Create New Board
                    </div>
                </a>



            </Col>
        )
    }
}

export default BoardAdd
番长猴子古一2020/03/13 20:11:48

setState is an asynchronous function so you might need to use it as,

this.setState({key:value},()=>{ callYourFunction(this.state.key) });
Sam神乐番长2020/03/13 20:11:48

when i was running the code and checking my output at console it showing the that it is undefined. After i search around and find something that worked for me.

componentDidUpdate(){}

I added this method in my code after constructor(). check out the life cycle of react native workflow.

https://images.app.goo.gl/BVRAi4ea2P4LchqJ8

ItachiHarry2020/03/13 20:11:48

setState is an async operation so as go with all async operations you can use a callback function.

this.setState({boardAddModalShow:newValue},
             ()=>{//code you want to run});
LJinJin2020/03/13 20:11:48

根据React Docs

React does not guarantee that the state changes are applied immediately. This makes reading this.state right after calling setState() a potential pitfall and can potentially return the existing value due to async nature . Instead, use componentDidUpdate or a setState callback that is executed right after setState operation is successful.Generally we recommend using componentDidUpdate() for such logic instead.

Example:

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      counter: 1
    };
  }
  componentDidUpdate() {
    console.log("componentDidUpdate fired");
    console.log("STATE", this.state);
  }

  updateState = () => {
    this.setState(
      (state, props) => {
        return { counter: state.counter + 1 };
      });
  };
  render() {
    return (
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
        <button onClick={this.updateState}>Update State</button>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

卡卡西Davaid2020/03/13 20:11:48
openAddBoardModal=async()=>{
    await this.setState({ boardAddModalShow: true });
    console.log(this.state.boardAddModalShow);
}
Gil米亚2020/03/13 20:11:48

setState()是异步的。验证状态是否正在更新的最佳方法是在componentDidUpdate()而不是在console.log(this.state.boardAddModalShow)after后面this.setState({ boardAddModalShow: true })

根据React Docs

将setState()视为请求而不是立即更新组件的命令。为了获得更好的感知性能,React可能会延迟它,然后在一次通过中更新几个组件。React不能保证状态更改立即生效

理查德村村小宇宙2020/03/13 20:11:48
 this.setState({
    isMonthFee: !this.state.isMonthFee,
  }, () => {
    console.log(this.state.isMonthFee);
  })
宝儿DavaidL2020/03/13 20:11:48

setState()并不总是立即更新组件。它可能会批量更新或将更新推迟到以后。这使得在调用setState()潜在陷阱之后立即阅读this.state 而是使用componentDidUpdatesetState回调(setState(updater, callback)),保证在应用更新后都会触发两者。如果您需要基于先前的状态来设置状态,请阅读下面的updater参数。

setState()除非shouldComponentUpdate()返回false,否则将始终导致重新渲染如果正在使用可变对象,并且无法在中实现条件渲染逻辑shouldComponentUpdate(),则setState()仅在新状态与先前状态不同时进行调用才能避免不必要的重新渲染。

第一个参数是带有签名的updater函数:

(state, props) => stateChange

state是在应用更改时对组件状态的引用。它不应该直接突变。相反,应该通过基于状态和道具的输入来构建新对象来表示更改。例如,假设我们想通过props.step增加状态值:

this.setState((state, props) => {
    return {counter: state.counter + props.step};
});
JinJin乐2020/03/13 20:11:48

幸运的是, setState进行了回调。这是我们获取更新状态的地方。考虑这个例子。

this.setState(
    { name: "Mustkeom" },
      () => {                        //callback
        console.log(this.state.name) // Mustkeom
      }
);

因此,当回调触发时,this.state是更新后的状态。您可以在回调中获取突变/更新的数据。

乐小小2020/03/13 20:11:48

是的,因为setState是一个异步函数。在编写设置状态后立即设置状态的最佳方法是使用Object.assign,例如:例如,要将属性isValid设置为true,请按照以下步骤进行操作


Object.assign(this.state,{isValid:true})


编写此行后,即可访问更新状态。

Ss Yy2020/03/13 20:11:48

您的状态需要一段时间才能突变,由于console.log(this.state.boardAddModalShow)状态在突变之前就已执行,因此您会获得先前的值作为输出。因此,您需要在回调中将控制台写入setState函数

openAddBoardModal(){
        this.setState({ boardAddModalShow: true }, function () {
             console.log(this.state.boardAddModalShow);
        });

}

setState is asynchronous. It means you can’t call setState on one line and assume state has changed on the next.

according to React docs

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

Why would they make setState async

This is because setState alters the state and causes rerendering. This can be an expensive operation and making it synchronous might leave the browser unresponsive.

Thus the setState calls are asynchronous as well as batched for better UI experience and performance.

十三泡芙猿2020/03/13 20:11:48

由于setSatate是异步函数,因此您需要像这样将状态作为回调进行控制台。

openAddBoardModal(){
    this.setState({ boardAddModalShow: true }, () => {
        console.log(this.state.boardAddModalShow)
    });
}
猴子卡卡西2020/03/13 20:11:48

如果您想跟踪状态是否正在更新,那么另一种做同一件事的方法是

_stateUpdated(){
  console.log(this.state. boardAddModalShow);
}

openAddBoardModal(){
  this.setState(
    {boardAddModalShow: true}, 
    this._stateUpdated.bind(this)
  );
}

这样,您每次尝试更新状态进行调试时都可以调用方法“ _stateUpdated”。

古一达蒙2020/03/13 20:11:48

这个回调真的很混乱。只需使用async await代替:

async openAddBoardModal(){
    await this.setState({ boardAddModalShow: true });
    console.log(this.state.boardAddModalShow);
}