Javascript 设置状态不';不要立即更新状态

Javascript 设置状态不';不要立即更新状态,javascript,reactjs,ecmascript-6,Javascript,Reactjs,Ecmascript 6,我想问一下,为什么在执行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 BoardAd

我想问一下,为什么在执行
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 }); // set boardAddModalShow to true

        /* After setting a new state it still returns 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
从“React”导入React;
从“react bootstrap/lib/Grid”导入网格;
从“react bootstrap/lib/Row”导入行;
从“react bootstrap/lib/Col”导入Col;
从“components/board/BoardAddModal.jsx”导入BoardAddModal;
从“styles/boarditem.css”导入样式;
类BoardAdd扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
boardAddModalShow:错误
};    
this.openAddBoardModal=this.openAddBoardModal.bind(this);
}
openAddBoardModal(){
this.setState({boardAddModalShow:true});//将boardAddModalShow设置为true
/*设置新状态后,它仍然返回一个假值*/
console.log(this.state.boardAddModalShow);
}
render(){
返回(
);
}
}
导出默认BoardAdd

您的状态需要一些时间才能发生变化,并且由于
console.log(this.state.boardAddModalShow)
在状态发生变化之前执行,因此您可以将上一个值作为输出。因此,您需要在回调中将控制台写入
setState
函数

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

setState
是异步的。这意味着你不能在一条线上打电话,然后假设下一条线上的状态发生了变化

根据

setState()
不会立即改变此.state,但会创建一个 等待状态转换。调用此函数后访问此.state 方法可能返回现有值。没有 保证对setState的调用和可能发生的调用的同步操作 为提高性能而进行批处理

他们为什么要使
setState
async 这是因为
setState
改变状态并导致重新招标。这 可能是一个昂贵的操作,使其同步可能会离开 浏览器没有响应

因此,
setState
调用是异步的,并且是批处理的,以获得更好的性能 用户界面体验和性能


幸运的是
setState()
接受回调。这就是我们得到更新状态的地方

考虑这个例子

this.setState({name:“myname”},()=>{
//回拨
console.log(this.state.name)//myname
});
因此,当调用回调时,this.state是更新状态。

您可以在回调中获取经过修改/更新的数据。

因为setstate是一个异步函数,所以您需要像这样将状态作为回调进行控制台

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

如果要跟踪状态是否正在更新,则另一种方法是

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

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

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

此回调非常混乱。只需使用异步等待即可:

async openAddBoardModal(){
    await this.setState({ boardAddModalShow: true });
    console.log(this.state.boardAddModalShow);
}
setState()
并不总是立即更新组件。它可以批处理更新或将更新推迟到以后。这使得在调用
setState()
之后立即读取This.state成为一个潜在的陷阱。相反,使用
componentdiddupdate
setState
回调(
setState(updater,callback)
),这两种回调都保证在应用更新后触发。如果需要基于上一个状态设置状态,请阅读下面的updater参数

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

第一个参数是具有签名的更新程序函数:

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

this.setState((state, props) => {
    return {counter: state.counter + props.step};
});
setState()
是异步的。验证状态是否正在更新的最佳方法是在
componentDidUpdate()
中,而不是在
this.setState({boardAddModalShow:true})之后放置
console.log(this.state.boardAddModalShow)

将setState()视为更新组件的请求,而不是即时命令。为了更好地感知性能,React可能会延迟它,然后在一次过程中更新多个组件。React不保证立即应用状态更改

React不保证立即应用状态更改。 这使得在调用setState()之后立即读取This.state成为一个潜在的
陷阱
,并且由于
异步
的性质,可能会返回
现有的
值。 相反,请使用
componentdiddupdate
或在setState操作成功后立即执行的
setState
回调。通常,我们建议对此类逻辑使用
componentdiddupdate()

例子:
从“React”导入React;
从“react dom”导入react dom;
导入“/styles.css”;
类应用程序扩展了React.Component{
构造函数(){
超级();
此.state={
柜台:1
};
}
componentDidUpdate(){
log(“componentDidUpdate已启动”);
console.log(“STATE”,this.STATE);
}
updateState=()=>{
这是我的国家(
(状态、道具)=>{
返回{计数器:state.con
 this.setState({
    isMonthFee: !this.state.isMonthFee,
  }, () => {
    console.log(this.state.isMonthFee);
  })
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);

componentDidUpdate(){}
Element is rendered: 5 15
re-render because x changed: 5
(press x button)
x before setting: 5
x in *line* after setting: 5
Element is rendered: 10 15
re-render because x changed: 10
(press y button)
Element is rendered: 10 20