728x90
useState의 두 가지 특이점에 대해서 기록하려고 한다.
두 가지 특징 모두 useState가 반환하는 세터 함수에 의해 일어나는 일이다.
Batch Update
- state값의 업데이트는 16ms 단위로 이루어진다.
- 16ms 내 변경된 state값은 한 번에 업데이트된다.
- 때문에 setState 작업이 비동기적으로 작동하는 것이다.
import { useState, useEffect } from "react";
export default function App() {
const [num, setNum] = useState(0); //초기값을 0으로 한 state
const handlePlus = () => {
setNum(num + 1); //기존 num 값에 1을 더하는 작업을 3번 함
setNum(num + 1);
setNum(num + 1);
};
return (
<div>
<p>{num}</p> //num 값을 보여줌
<button onClick={handlePlus}>plus</button> //click 이벤트가 발생하면 handlePlus 함수 호출
</div>
);
}
- 코드를 보면 plus 버튼을 눌렀을 때 당연히 3이 증가한 num 값이 보일 것이라고 생각된다.
- 하지만 1씩 증가한 것을 볼 수 있다.
- Batch Update가 되었기 때문이다.
- setNum(num+1)코드에서 num 값은 세 번의 코드 모두 같은 초기값을 전달받기 때문에 결과값이 1이 되는 것이다.
비동기 작업
- 앞서 언급한대로 세터 함수는 비동기적으로 작동한다.
- 처음 useState를 배웠을 때 흔히 하는 실수가 있다.
import { useState, useEffect } from "react";
export default function App() {
const [num, setNum] = useState(0);
const handlePlus = () => {
setNum(num + 1);
console.log(num); //증가한 num 값을 console에 출력
};
return (
<div>
<p>{num}</p>
<button onClick={handlePlus}>plus</button>
</div>
);
}
- 업데이트된 state 값이 콘솔에 출력될 것이라고 예상했을 것이다.
- 하지만 세터 함수가 비동기적으로 작동하기 때문에 업데이트 되기 전의 num 값이 출력되었다.
- 그렇다면 이러한 문제들을 어떻게 해결해야 할까?
함수형 업데이트
- 먼저 앞서 연속적인 세터 함수의 사용으로 원하는 값을 얻지 못했던 문제부터 해결해보자.
- 세터 함수에서 state값을 인자로 넘기는 콜백 함수를 사용해 값을 업데이트하면 된다.
import { useState, useEffect } from "react";
export default function App() {
const [num, setNum] = useState(0);
const handlePlus = () => {
setNum((num) => num + 1);
setNum((num) => num + 1);
setNum((num) => num + 1);
};
return (
<div>
<p>{num}</p>
<button onClick={handlePlus}>plus</button>
</div>
);
}
- 위처럼 함수형 업데이트를 사용하면 업데이트된 state값을 인자로 받기 때문에 원했던 결과를 얻을 수 있다.
useEffect
- useEffect의 Deps 배열을 사용하면 비동기적으로 처리되는 문제를 해결할 수 있다.
import { useState, useEffect } from "react";
export default function App() {
const [num, setNum] = useState(0);
useEffect(() => {
console.log(num);
}, [num]);
const handlePlus = () => {
setNum((num) => num + 1);
};
return (
<div>
<p>{num}</p>
<button onClick={handlePlus}>plus</button>
</div>
);
}
- 위의 코드처럼 useEffect를 사용해서 deps 배열에 num을 추가했다.
- num의 값이 업데이트되면 바로 console.log 함수가 실행되므로 업데이트된 state 값을 바로 볼 수 있다.
- 이렇게 동기적으로 작동하는 작업들에서 업데이트된 state값을 사용하고 싶다면 useEffect를 사용하면 된다.
728x90
'Frontend > React' 카테고리의 다른 글
[React] 리액트 토스트 메세지 구현하기(react-toastify) (0) | 2022.09.27 |
---|---|
[React] react-hook-form 사용법(useForm, watch) (0) | 2022.08.07 |
[React]Router v6 사용법, 관련 Hooks 정리 (0) | 2022.07.23 |
[React] React useEffect/componentDidMount/componentDidUpdate/componentWillUnmount (0) | 2022.07.14 |
[React] useState로 button과 input 관리하기 (0) | 2022.07.11 |