Подтвердить что ты не робот

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
4b9b3361

Ответ 1

Этот обратный вызов действительно беспорядочен. Вместо этого просто используйте async:

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

Ответ 2

Вашему состоянию требуется некоторое время, чтобы мутировать, и поскольку console.log(this.state.boardAddModalShow) выполняется до того, как состояние мутирует, вы получите предыдущее значение как результат. Поэтому вам нужно написать консоль в обратном вызове функции setState

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

}

setState является асинхронным. Это означает, что вы не можете вызвать setState на одной строке и предположить, что состояние изменилось на следующем.

в соответствии с документами React

setState() не сразу мутирует this.state но создает ожидающий переход состояния. Доступ к this.state после вызова этого метода может потенциально вернуть существующее значение. Нет гарантии синхронной работы вызовов setState, и вызовы могут быть собраны для повышения производительности.

Почему они должны сделать setState async

Это связано с тем, что setState изменяет состояние и вызывает реинжиниринг. Это может быть дорогостоящей операцией, и сделать ее синхронной может оставить браузер невосприимчивым.

Таким образом, вызовы setState асинхронны, а также собраны для лучшего опыта и производительности интерфейса.

Ответ 3

К счастью, setState принимает обратный вызов. И вот где мы получаем обновленное состояние. Рассмотрим этот пример.

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

Поэтому, когда сработает обратный вызов, this.state является обновленным состоянием. Вы можете получить измененные/обновленные данные в обратном вызове.

Ответ 4

Поскольку setSatate - это асинхронная функция, поэтому вам нужно настроить состояние как обратный вызов, подобный этому.

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

Ответ 5

setState() не всегда сразу обновляет компонент. Это может пакетировать или отложить обновление до позже. Это делает чтение this.state сразу после вызова setState() потенциальной ловушкой. Вместо этого используйте componentDidUpdate или setState вызов setState(updater, callback) setState (setState(updater, callback)), который гарантированно setState(updater, callback) после применения обновления. Если вам нужно установить состояние на основе предыдущего состояния, прочтите об аргументе средства обновления ниже.

setState() всегда будет приводить к повторному рендерингу, если shouldComponentUpdate() возвращает false. Если используются изменяемые объекты и логика условного рендеринга не может быть реализована в shouldComponentUpdate(), то вызов setState() только в том случае, если новое состояние отличается от предыдущего, позволит избежать ненужных повторных визуализаций.

Первый аргумент - это функция обновления с подписью:

(state, props) => stateChange

state - это ссылка на состояние компонента во время применения изменения. Это не должно быть непосредственно видоизменено. Вместо этого изменения должны быть представлены путем создания нового объекта на основе входных данных от состояния и реквизита. Например, предположим, что мы хотели увеличить значение в состоянии с помощью props.step:

this.setState((state, props) => {
    return {counter: state.counter + props.step};
});

Ответ 6

Если вы хотите отслеживать состояние обновляется или нет, то другой способ сделать то же самое

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

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

Таким образом вы можете вызывать метод "_stateUpdated" каждый раз, когда вы пытаетесь обновить состояние для отладки.

Ответ 7

Да, потому что setState является асинхронной функцией. Лучший способ установить состояние сразу после записи set set - использовать Object.assign следующим образом: Например, если вы хотите установить для свойства isValid значение true, сделайте это следующим образом


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


Вы можете получить доступ к обновленному состоянию сразу после написания этой строки.

Ответ 8

setState() является асинхронным. Лучший способ проверить, обновляется ли состояние, - это в componentDidUpdate() а не помещать console.log(this.state.boardAddModalShow) после this.setState({ boardAddModalShow: true }).

в соответствии с React Docs

Думайте о setState() как о запросе, а не как о немедленной команде для обновления компонента. Для лучшего восприятия производительности React может задержать ее, а затем обновить несколько компонентов за один проход. React не гарантирует, что изменения состояния будут применены немедленно

Ответ 9

 this.setState({
    isMonthFee: !this.state.isMonthFee,
  }, () => {
    console.log(this.state.isMonthFee);
  })

Ответ 10

Согласно React Docs

React не гарантирует, что изменения состояния будут применены немедленно. Это делает чтение this.state сразу после вызова setState() потенциальной pitfall и может потенциально вернуть existing значение из-за async характера. Вместо этого используйте componentDidUpdate или setState вызов setState который выполняется сразу после успешной операции setState. Обычно мы рекомендуем использовать componentDidUpdate() для такой логики.

Пример:

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);

Ответ 11

setState - это асинхронная функция, поэтому вам, возможно, придется использовать ее как

this.setState({key:value},()=>{ callYourFunction(this.state.key) });