티스토리 뷰
최근 면접에서 useState 일괄처리에 대한 질문을 받았습니다. 그 동안 많이 사용해본 useState 였지만 일괄처리에 대해 들어본적이 없어서 대답을 못했습니다. 그래서 이번 기회에 useState 일괄처리에 대해 알아보려고 합니다.
useState
먼저 기본적으로 useState는 상태 관리 기능을 하며 리액트에 내장되어 있는 Hook입니다. 아래의 코드는 이 Hook을 활용하여 버튼을 클릭했을 때 value값이 1씩 증가하는 간단한 예시입니다.
const Example = () => {
const [value, setValue] = useState(0);
return <button onClick={() => setValue(value+1)}>1더하기</button>
}
먼저, useState(0)를 호출하여 초기 상태 값을 0으로 설정한 value 상태 변수와 이 상태를 업데이트할 수 있는 setValue 함수를 선언하고 초기화했습니다. 이 때 value는 현재의 숫자를 나타내며, setValue 함수는 새로운 값을 설정할 때 사용됩니다.
이후, 버튼을 클릭했을 때 onClick 이벤트에 의해 setValue 함수를 호출하여 value값을 1씩 증가하도록 했습니다. 이 때 value 상태값이 증가함에 따라 Example 컴포넌트가 리렌더링이 발생합니다.
일괄처리
useState의 일괄처리란 setState을 모아서 한번에 일괄처리(batch update)를 하여 컴포넌트의 리렌더링 횟수를 최소화하여 성능 향상하는 것입니다. 조금 더 쉬운 이해를 위해 아래의 코드를 구현해봤습니다.
const App = () => {
const [first, setFirst] = useState(0);
const [second, setSecond] = useState(0);
useEffect(() => {
//마운트 될 때의 콘솔은 제외
console.log('update');
}, [first, second]);
const onBetchUpdate = () => {
setSecond(second + 1);
setFirst(first + 1);
};
return (
<>
<button onClick={onBetchUpdate}>버튼</button>
</>
);
};
export default App;
// 'update' (한줄ㅡ 한번에 업데이트 -> 한번의 리렌더링)
App 컴포넌트 안에는 first와 second라는 상태가 2개 존재합니다. 이 때 버튼을 클릭하면 onBetchUpdate 함수가 호출되고 setSecond와 setFirst 함수에 의해 2개의 상태가 업데이트 됩니다. 여기서 2개의 상태 업데이트가 하나씩 되는지 또는 동시에 되는지 명확히 알아야 합니다. 만약 2개의 상태 업데이트가 하나씩 된다면 useEffect 의존성 배열에 의해 'update'는 두 번 출력될 것이고, 동시에 업데이트가 된다면 'update'는 한 번만 출력될 것입니다.
그렇다면 위의 코드를 실행했을 때의 결과는 어떻게 나올까요?
마운트 됐을 때의 콘솔은 제외하고 버튼을 한 번 클릭했을 때 'update'가 한 번 출력됐습니다. 즉 2개의 상태가 동시에 업데이트가 되어 리렌더링이 한번만 된다는 뜻입니다. 결국 이것이 useState 일괄처리입니다.
그렇다면 약 first와 second 2개의 상태가 하나씩 업데이트 된다면 어떻게 될까요?
first의 상태가 업데이트되어 리렌더링이 발생하고, 그 후 second의 상태가 업데이트되어 리렌더링이 발생하여 총 2번의 리렌더링이 발생하고 결국 'update'가 2번 출력 될 것입니다. 이제 위에서 정의했던 'setState을 모아서 한번에 일괄처리(batch update)를 하여 컴포넌트의 리렌더링 횟수를 최소화하여 성능 향상하는 것이다.'라는 말이 이해가 되실 것입니다.
하지만 여기서 예외가 있습니다. 리액트 18이전을 기준으로 비동기 처리 async/await, Promise, setTimeout, 이벤트 등에 대해서는 일괄처리가 되지 않으며, 리액트 18이상부터는 모두 자동 일괄처리 된다고 리액트 업데이트 로그 18.0.0에 나와있습니다.
만약 리액트 18이상일 때, 자동 일괄처리되는 것을 막고 싶을 때는 어떻게 해야될까요?
바로 ReactDOM.flushSync()를 사용하여 막을 수 있다고 리액트 문서에 나와 있습니다. 이를 적용해보고자 위에서 사용했던 예시 코드를 가져와서 일괄처리를 막아보았습니다.
마운트 됐을 때의 콘솔은 제외하고 결국 일괄처리가 막아져서 상태값이 동시에 업데이트 되지 않고 하나씩 업데이트 되어 'update'가 두 번 출력되는 것을 볼 수 있습니다.
'프론트엔드' 카테고리의 다른 글
ChatGpt를 사용하여 작업 중인 코드 개선하기 (0) | 2023.02.16 |
---|---|
달력 만들고 해당 날짜에 할 일 보여주기 (2) | 2022.09.19 |
어떤 상태 관리 라이브러리를 선택할까?(State, Context API, Redux, React-Query, Recoil) (0) | 2022.08.28 |
웹팩 데브 서버 설정하기 (0) | 2022.08.12 |
바벨 로더 설정하기 (0) | 2022.08.11 |
- Total
- Today
- Yesterday