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
이 콜백은 정말 지저분합니다. 대신 async await를 사용하십시오.
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를 비동기로 만들까요?
이는 setState가 상태를 변경하고 다시 렌더링하기 때문입니다. 이는 비용이 많이 드는 작업 일 수 있으며 동기식으로 만들면 브라우저가 응답하지 않을 수 있습니다.
따라서 setState 호출은 더 나은 UI 경험과 성능을 위해 비동기식이며 일괄 처리됩니다.
다행히 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()
항상 구성 요소를 즉시 업데이트하지는 않습니다. 나중에 업데이트를 일괄 처리하거나 연기 할 수 있습니다. 이것은 setState()
잠재적 인 함정 을 호출 한 직후 this.state를 읽도록 합니다. 대신 componentDidUpdate
또는 setState
콜백 ( setState(updater, callback)
)을 사용 하세요 .이 중 하나는 업데이트가 적용된 후에 실행됩니다. 이전 상태를 기반으로 상태를 설정해야하는 경우 아래 업데이트 프로그램 인수에 대해 읽어보세요.
setState()
shouldComponentUpdate()
false를 반환 하지 않는 한 항상 다시 렌더링 합니다. 변경 가능한 객체를 사용하고에서 조건부 렌더링 논리를 구현할 수없는 경우 새 상태가 이전 상태와 다를 때만 shouldComponentUpdate()
호출 setState()
하면 불필요한 다시 렌더링을 방지 할 수 있습니다.
The first argument is an updater function with the signature:
(state, props) => stateChange
state
is a reference to the component state at the time the change is being applied. It should not be directly mutated. Instead, changes should be represented by building a new object based on the input from state and props. For instance, suppose we wanted to increment a value in state by props.step:
this.setState((state, props) => {
return {counter: state.counter + props.step};
});
If you want to track the state is updating or not then the another way of doing the same thing is
_stateUpdated(){
console.log(this.state. boardAddModalShow);
}
openAddBoardModal(){
this.setState(
{boardAddModalShow: true},
this._stateUpdated.bind(this)
);
}
This way you can call the method "_stateUpdated" every time you try to update the state for debugging.
Yes because setState is an asynchronous function. The best way to set state right after you write set state is by using Object.assign like this: For eg you want to set a property isValid to true, do it like this
Object.assign(this.state, { isValid: true })
You can access updated state just after writing this line.
setState()
is asynchronous. The best way to verify if the state is updating would be in the componentDidUpdate()
and not to put a console.log(this.state.boardAddModalShow)
after this.setState({ boardAddModalShow: true })
.
according to React Docs
Think of setState() as a request rather than an immediate command to update the component. For better perceived performance, React may delay it, and then update several components in a single pass. React does not guarantee that the state changes are applied immediately
this.setState({
isMonthFee: !this.state.isMonthFee,
}, () => {
console.log(this.state.isMonthFee);
})
According to 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 theexisting
value due toasync
nature . Instead, usecomponentDidUpdate
or asetState
callback that is executed right after setState operation is successful.Generally we recommend usingcomponentDidUpdate()
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);
setState is an asynchronous function so you might need to use it as,
this.setState({key:value},()=>{ callYourFunction(this.state.key) });
참고URL : https://stackoverflow.com/questions/41278385/setstate-doesnt-update-the-state-immediately
'developer tip' 카테고리의 다른 글
결과를 기다리지 않는 php exec 명령 (또는 유사) (0) | 2020.11.10 |
---|---|
MongoDB 셸에서 복제 세트에 어떻게 연결합니까? (0) | 2020.11.10 |
jquery에서 배열을 어떻게 생성합니까? (0) | 2020.11.10 |
내가 소유하지 않은 브랜치에 대한 병합되지 않은 풀 리퀘스트를 어떻게 가져올 수 있습니까? (0) | 2020.11.10 |
UIView를 이미지로 변환하는 방법 (0) | 2020.11.09 |