- 리액트에서 setState는 비동기 동작인가요, 동기동작인가요?
- setState가 비동기 동작을 취했을 때 얻을 수 있는 이점은 무엇인가요?
setState는 비동기 동작입니다.
setState가 비동기로 동작을 하는 이유는 렌더링을 더 적게 하면서 화면에 최신값을 보여주기 위함입니다.
useState의 state hook으로 살펴보겠습니다.
import {useState} from 'react';
function Example() {
const [count, setCount] = useState(0);
function handleAlertClick() {
setCount(1);
setCount(2);
setCount(3);
}
console.log('rerendered');
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
<button onClick={handleAlertClick}>Show alert</button>
</div>
);
}
export default Example;
위와 같은 컴포넌트가 있습니다.
이때 handleAlertClick이 실행되면 count는 3이 되고 rerendered는 한번만 출력됩니다.
import {useState} from 'react';
function Example() {
const [count, setCount] = useState(0);
const [test, setTest] = useState(0);
const [code, setCode] = useState(0);
function handleAlertClick() {
setCount(count + 1);
setTest(test + 1);
setCode(code + 1);
}
console.log('rerendered')
return (
<div>
<p>You clicked {code} times</p>
<p>You clicked {count} times</p>
<p>You clicked {test} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
<button onClick={handleAlertClick}>Show alert</button>
</div>
);
}
export default Example;
위와 같은 컴포넌트가 또 있습니다.
handleAlertClick이 실행되면 count, test, code의 값들이 1로 바뀌고 rerendered는 1번만 출력됩니다.
만약 setState가 동기적인 실행을 한다면 어떻게 될까요??
setCount가 실행되고 렌더링이 일어나고
setTest가 실행되고 렌더링이 일어나고
setCode가 실행되고 렌더링이 일어나게 될것입니다.
분명 비동기로 실행될때와 결과는 같지만 렌더링이 3번 일어나게 되어 같은 결과에 더 많은 렌더링이 일어나게 됩니다.
따라서 하나의 핸들러 함수에서 상태가 변화되는 경우 한번에 모아서 실행하기 위해 비동기로 동작을 하게 됩니다.
이러한 것을 배칭이라 합니다.
배칭은 React가 더 나은 성능을 위해 여러개의 state 업데이트를 하나의 리렌더링으로 묶는것을 의미합니다.
결국 비동기로 동작함으로써 더 적은 렌더링으로 동기적 실행을 했을때와 같은 화면을 보여줄 수 있습니다.
그렇다면 아래의 결과는 어떻게 출력 될까요?
import {useState} from 'react';
function Example() {
const [count, setCount] = useState(0);
const [test, setTest] = useState(0);
const [code, setCode] = useState(0);
function handleAlertClick() {
setTimeout(() => {
setCount(count + 1);
setTest(test + 1);
setCode(code + 1);
}, 0)
}
console.log('rerendered')
return (
<div>
<p>You clicked {code} times</p>
<p>You clicked {count} times</p>
<p>You clicked {test} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
<button onClick={handleAlertClick}>Show alert</button>
</div>
);
}
export default Example;
handleAlertClick 함수가 실행되면 rerendered는 3번 출력 됩니다.
렌더링이 3번 일어나게 되는 것이죠
리액트 에서는 콜백함수로 일어나는 state를 아직 배칭할수가 없습니다.
콜백함수에서도 배칭할 수 있게 해주는 것이 react의 18버전에 나왔습니다.
아래는 react18에서의 배칭에 관한 글입니다.
react 18을 접하고 나중에 주요 기능에 대해 기록할 수 있도록 하겠습니다.
https://immigration9.github.io/react/2021/06/12/automatic-batching-react.html
'Frontend > React' 카테고리의 다른 글
React useReducer 🌱 (0) | 2022.04.02 |
---|---|
React typescript 에서 dataset 이용하기 😢 (0) | 2022.04.01 |
React.memo 🌱 (0) | 2022.03.27 |
React useCallback, useMemo (0) | 2022.03.27 |
React 의존성 배열 🌱 (0) | 2022.03.27 |