React에서 사용하는 개념 중 하는 상태관리다.
상태를 기준으로 View를 그리기 때문에 일반 변수로 사용하지 않고 setState로 상태를 할당한다.
이벤트 핸들러에서 setState 이후 바로 상태값을 참조하여 다른 작업을 할 때 문제가 생기게 된다.
React의 setState등이 비동기적으로 작동하는 이유는 일정 시간동안 변화하는 상태를 모아
한꺼번에 렌더링 하기 위해서다.
How to force batching?
ReactDOM.unstable_batchUpdate 리액트 내부 API로 한 이벤트 핸들러에서 발생하는 모든
업데이트를 단일 렌더 패스로 일괄 처리 할 수 있다.
이는 불필요한 렌더 함수 호출을 줄일 수 있게 된다.
Automatic Batching
페이스북에서 리액트의 변화된 점이 있다.
그 중 하나인 자동으로 여러개의 state를 단일 렌더에서 처리해주는 것이다.
function App() {
const [count, setCount] = useState(0);
const [flag, setFlag] = useState(false);
function handleClick() {
setCount(c => c+1); // Does not re-render yet
setFlag(f => !f); // Does not re-render yet
//React will only re-render once at the end (that's batching)
}
return (
<div>
<button onClick={handleClick}>Next</button>
<h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
</div>
);
}
참고로 fetch를 이용해서 state 업데이트를 handleClick에서 실행된다면
즉, 독립된 업데이트를 실행해야 되는 상황이라면 이벤드가 이미 처리 된 후 상태를 업데이트 합니다.
function App() {
const [count, setCount] = useState(0);
const [flag, setFlag] = useState(false);
function handleClick() {
fetchSomething().then(() => {
// React 17 and earlier does NOT batch these:
setCount(c => c + 1); // Causes a re-render
setFlag(f => !f); // Causes a re-render
});
}
return (
<div>
<button onClick={handleClick}>Next</button>
<h1 style={{ color: flag ? "blue" : "black" }}>{count}</h1>
</div>
);
}
what if i don't want to batch?
batch가 필요하지 않는 경우라면 flushSync를 사용하여 컴포넌트를 re-render 할 수 있다.
import { flushSync } from 'react-dom'; //Note: react-dom, not react
function handleClick() {
flushSync(() => {
setCounter(c => c + 1);
});
// React has updated the DOM by now
flushSync(() => {
setFlag(f => !f);
});
// React has updated the DOM by now
}
https://medium.com/swlh/react-state-batch-update-b1b61bd28cd2
'리액트' 카테고리의 다른 글
Lazy Loading (0) | 2021.06.29 |
---|---|
개발 환경 설정 (0) | 2021.06.21 |
React Router 정리 (0) | 2021.06.15 |
Receives *all* click events (0) | 2021.05.12 |
Fix a missing dependency warning (0) | 2021.05.07 |