일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 이펙티브타입스크립트
- SemVer
- framer-motion
- CSS
- JUNCTION2023
- Framer motion
- 개발자를 위한 글쓰기 가이드
- ASP.NET
- 글또 10기
- 타입스크립트
- typescript
- 글또
- TS
- 코드트리
- framer
- 캐나다개발자
- VS Code
- 알고리즘
- Effective Typescript
- JSBridge
- CSS방법론
- Semantic Versioning
- 캐나다취준
- useState
- 테오의 스프린트
- 시스템디자인
- React-Router-Dom
- 개발자 원칙
- react
- 회고
- Today
- Total
큰 꿈은 파편이 크다!!⚡️
setState가 비동기인 이유? 본문
setState했는데 값이 안바뀐다?
export default function App() {
const [count, setCount] = useState(0);
const onAdd = () => {
setCount(count + 1);
console.log(count);
};
return (
<div>
<div>{count}</div>
<button onClick={onAdd}>+1</button>
</div>
);
}
위 코드를 실행해보면, 화면에 나타나는 count
는 정상적으로 1이지만, 콘솔 창에는 0이 출력된다.
단순히 화면을 리렌더링 하는데에는 문제가 없지만 아래와 같이 setState
이후 상태값을 바로 다른 로직에 사용하면 원하지 않는 결과를 맛보게 된다.
export default function App() {
const [count, setCount] = useState(0);
const [biggerCount, setBiggerCount] = useState(0);
const onAdd = () => {
setCount(count + 1);
console.log("onAdd count: " + count);
setBiggerCount(count + 1); //업데이트된 count값을 사용할 것을 기대한다
console.log("onAdd biggerCount: " + biggerCount);
};
useEffect(() => {
console.log("useEffect count: " + count);
}, [count]);
return (
<div>
<div>{count}</div>
<button onClick={onAdd}>+1</button>
</div>
);
}
코드를 실행하면 count
가 즉시 변경되지는 않아도, 변경되긴 한다는 것을 알 수 있다. 즉, setState는 비동기 함수이다.
onAdd count: 0
onAdd biggerCount: 0
useEffect count: 1
React batch updating: setState는 비동기로 수행된다
State Updates May Be Asynchronous
React may batch multiple setState() calls into a single update for performance.
React 공식 문서에서는 상태 갱신이 비동기로 수행됨을 명시하고 있다. 즉 위 예시에서는 동기함수인 console.log
가 먼저 실행되기 때문에 상태값이 갱신되기 이전의 값을 출력한다.
그렇다면 이렇게 동작하는 이유는 뭘까?
React state batch updating
setState로 매번 상태가 업데이트될때마다 리렌더링을 한다면 매번 리액트의 컴포넌트 비교 알고리즘이 실행될 것이고, 렌더링에 소모되는 비용이 많아지게 된다. 단적인 예로, 한 상태값에 대해 연속으로 업데이트를 해준 후 최종 값만 사용자의 화면에 보여주는 경우에는 이러한 방법이 비효율적일 것이다.
따라서 React는 batch updating
이라는 특징을 통해 일정 시간마다 상태값이 변경된 컴포넌트들을 모아서 한번에 리렌더링하여 효율성을 높인다.
아래 샘플을 돌려보면 세 개의 상태값을 연속으로 갱신했지만 렌더링 횟수는 1씩 증가한다.
상태값을 갱신하자마자 사용하고 싶다면?
1. setState에서 콜백함수 사용하기
export default function App() {
const [count, setCount] = useState(0);
const onAdd = () => {
setCount((prev) => {
console.log(prev + 1);
return prev + 1;
});
};
return (
<div>
<div>{count}</div>
<button onClick={onAdd}>+1</button>
</div>
);
}
2. useEffect로 해당 상태값 트래킹하기
export default function App() {
const [count, setCount] = useState(0);
const onAdd = () => {
setCount(count + 1);
};
useEffect(() => {
console.log(count); //count가 갱신된 후에 필요한 연산을 수행
},[count]);
return (
<div>
<div>{count}</div>
<button onClick={onAdd}>+1</button>
</div>
);
}
참고자료 및 샘플코드
'Web FE' 카테고리의 다른 글
🔨 웹에서 RTSP 스트리밍 + video autoplay 삽질기 (0) | 2022.07.23 |
---|---|
🍪 쿠키와 세션 (feat. 웹에서 로그인을 유지하는 원리) (0) | 2022.07.09 |
예제로 이해하는 React Custom Hook (0) | 2022.06.25 |
Framer motion 순한맛 찍먹 (0) | 2022.05.29 |
react router dom6 적용하기 (0) | 2022.02.27 |