Ответ 1
Этот обратный вызов действительно беспорядочен. Вместо этого просто используйте async:
async openAddBoardModal(){
await this.setState({ boardAddModalShow: true });
console.log(this.state.boardAddModalShow);
}
Я хотел бы спросить, почему мое состояние не меняется, когда я делаю событие 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
Этот обратный вызов действительно беспорядочен. Вместо этого просто используйте async:
async openAddBoardModal(){
await this.setState({ boardAddModalShow: true });
console.log(this.state.boardAddModalShow);
}
Вашему состоянию требуется некоторое время, чтобы мутировать, и поскольку 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 асинхронны, а также собраны для лучшего опыта и производительности интерфейса.
К счастью, setState принимает обратный вызов. И вот где мы получаем обновленное состояние. Рассмотрим этот пример.
this.setState(
{ name: "Mustkeom" },
() => { //callback
console.log(this.state.name) // Mustkeom
}
);
Поэтому, когда сработает обратный вызов, this.state является обновленным состоянием. Вы можете получить измененные/обновленные данные в обратном вызове.
Поскольку setSatate - это асинхронная функция, поэтому вам нужно настроить состояние как обратный вызов, подобный этому.
openAddBoardModal(){
this.setState({ boardAddModalShow: true }, () => {
console.log(this.state.boardAddModalShow)
});
}
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};
});
Если вы хотите отслеживать состояние обновляется или нет, то другой способ сделать то же самое
_stateUpdated(){
console.log(this.state. boardAddModalShow);
}
openAddBoardModal(){
this.setState(
{boardAddModalShow: true},
this._stateUpdated.bind(this)
);
}
Таким образом вы можете вызывать метод "_stateUpdated" каждый раз, когда вы пытаетесь обновить состояние для отладки.
Да, потому что setState является асинхронной функцией. Лучший способ установить состояние сразу после записи set set - использовать Object.assign следующим образом: Например, если вы хотите установить для свойства isValid значение true, сделайте это следующим образом
Object.assign(this.state, { isValid: true })
Вы можете получить доступ к обновленному состоянию сразу после написания этой строки.
setState()
является асинхронным. Лучший способ проверить, обновляется ли состояние, - это в componentDidUpdate()
а не помещать console.log(this.state.boardAddModalShow)
после this.setState({ boardAddModalShow: true })
.
в соответствии с React Docs
Думайте о setState() как о запросе, а не как о немедленной команде для обновления компонента. Для лучшего восприятия производительности React может задержать ее, а затем обновить несколько компонентов за один проход. React не гарантирует, что изменения состояния будут применены немедленно
this.setState({
isMonthFee: !this.state.isMonthFee,
}, () => {
console.log(this.state.isMonthFee);
})
Согласно 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);
setState - это асинхронная функция, поэтому вам, возможно, придется использовать ее как
this.setState({key:value},()=>{ callYourFunction(this.state.key) });