✨ 한번 더 useState를 복습 매우 중요함.
useState
는 가장 기본적인 hook
이며, 함수 컴포넌트에서 가변적인 상태를 가지게 해줍니다.
그래서 useState
를 활용한 카운터나 Todo list
를 예시로 보았다.
const [state, setState] = useState(initialState);
useState라는 함수가 배열을 반환하고, 이를 구조 분해 문법으로 꺼내놓은 모습일 뿐입니다.
state
를 변수로 사용했고, setState
를 이용해 state
값을 수정할 수 있었습니다.
만약 state
가 원시 데이터타입이 아닌 객체 데이터 타입인 경우에는
불변성을 유지해줘야 합니다.
✨ state를 업데이트 할 수 있는 두가지 방법.
setState
를 사용하는 방식에 우리가 알고 있는 방식이 아닌
또 다른 방식이 존재하는데 이가 함수형 업데이트 방식입니다.
// 기존에 우리가 사용하던 방식
setState(number + 1);
// 함수형 업데이트
setState(() => {});
setState ()
안에 수정할 값이 아닌, 함수를 넣을 수 있습니다.
그 함수의 인자에서는 현재의 state
를 가져올 수 있고,
{}
안에서는 이 값을 변경하는 코드를 작성할 수 있습니다.
// 현재 number의 값을 가져와서 그 값에 +1을 더하여 반환한 것 입니다.
setState((currentNumber)=>{ return currentNumber + 1 });
먼저 2가지의 다른 코드를 보여줄 것입니다.
// src/App.js
// 1.
import { useState } from "react";
const App = () => {
const [number, setNumber] = useState(0);
return (
<div>
{/* 버튼을 누르면 1씩 플러스된다. */}
<div>{number}</div>
<button
onClick={() => {
setNumber(number + 1); // 첫번째 줄
setNumber(number + 1); // 두번쨰 줄
setNumber(number + 1); // 세번째 줄
}}
>
버튼
</button>
</div>
);
}
export default App;
// --------------------------------------------
// src/App.js
// 2.
import { useState } from "react";
const App = () => {
const [number, setNumber] = useState(0);
return (
<div>
{/* 버튼을 누르면 3씩 플러스 된다. */}
<div>{number}</div>
<button
onClick={() => {
setNumber((previousState) => previousState + 1);
setNumber((previousState) => previousState + 1);
setNumber((previousState) => previousState + 1);
}}
>
버튼
</button>
</div>
);
}
export default App;
먼저 위에서 일반 업데이트 방식은 number
가 1씩 증가합니다.
함수형 업데이트 방식은 number
가 3씩 증가합니다.
무슨 차이가 존재하냐면
일반 업데이트 방식은 버튼을 클릭했을 때,
setNumber
가 각각 실행되는게 아닌 배치(batch)
로 처리합니다.
즉 onClick
을 했을 때 setNumber
라는 명령을 세번 내리지만,
리액트는 그 명령을 하나로 모아 최종적으로 한번만 실행 시킵니다.
그래서 setNumber
을 3번 명령하던 100번 명령하던 1번만 실행됩니다.
그러나 함수형 업데이트 방식은 3번을 동시에 명령을 내리면,
그 명령을 모아 순차적으로 각각 1번씩 실행시킵니다.
즉 결과만 우리 눈에 보이는 것입니다.
부모 컴포넌트에 있는 어떠한 값이 자식 컴포넌트로
props
의 개념을 통해 전달될 수 있음을 알고 있습니다.
state
역시 마찬가지입니다. 한번 볼까요?
// src > App.jsx
import { useState } from 'react';
const App = () => {
const [count, setCount] = useState(0);
return (
<div>
<h1>여기는 부모컴포넌트입니다.</h1>
<span>현재 카운트 : {count}</span>
<Child /> {/* 여기에 어떤 props를 넘겨줘야 할까요? */}
</div>
)
}
export default App;
// --------------------------------------------
// src > components > Child.jsx
const Child = (props) => {
const handleAddCound = () => {
// ??
}
return <button>Count 1 증가</button>
}
export default Child;
넘겨주는 방법은 총 2가지인데
1) count
와 setCount
를 넘겨주는 방법으로
setCount(count + 1);
2) setCount
만 넘겨주는 방법
setCount(prev => prev + 1);
1번의 방법은 불필요한 props
전달이기 때문에
이럴 때 함수형 업데이트를 채택하여 작성하는 습관을 들이는 것이 좋습니다.
✨ 성능을 위해 setState()를 단일 업데이트(batch update)로 한번에 처리하기
불필요한 리-렌더링 방지는 렌더링 최적화하기 위해
한꺼번에 state
를 업데이트 하는 것입니다.
손님이 치킨 맥주 치킨무를 주문한다고 했을 때,
주문을 받는 사람이 하나씩 말할 때마다 하나씩 추가하지 않습니다.
한번에 주문을 받고 처리를 해야 동선이 짧은 느낌이다.