State Hooks
State Hooks
React 컴포넌트는 state를 활용하여 가변적인 상태(state)를 기억할 수 있습니다. 예를 들어, Form 컴포넌트는 사용자 입력을 저장하기 위해 state를 사용할 수 있으며, Counter 컴포넌트는 현재 카운터를 저장하기 위해 state를 사용할 수 있습니다.
React에서 함수 컴포넌트에 state를 추가하려면 다음 Hook 중 하나를 사용하면 됩니다.
1. useState는 사용자가 직접 업데이트할 수 있는 state 변수를 선언합니다.
2. useReducer는 reducer 함수 내부의 업데이트 로직을 사용하여 state 변수를 선언합니다.
useState Hook
useState는 가장 기본적인 Hook으로 사용자가 직접 업데이트할 수 있는 state 변수를 선언하고 관리할 수 있습니다.
useState 문법
const [state, setState] = useState(initialState)
useState는 처음 렌더링을 수행할 때 초기 상태 값(initialState)을 인수로 전달 받고, 최신 state의 값을 유지하는 변수와 그 값을 업데이트할 수 있는 함수를 반환합니다.
예제(Counter.js)
import { useState } from "react";
const Counter = () => {
// 0을 초기값으로 하는 state와 setState() 함수 생성
const [state, setState] = useState(0);
return (
<div>
<h1>State 값 : {state}</h1>
{/* setState() 함수를 사용하여 state의 값을 1씩 증가시킴 */}
<button onClick={() => setState(state + 1)}>1씩 증가</button>
</div>
);
};
export default Counter;
우리는 앞서 state에 대해 알아보면서 useState Hook에 대한 내용을 이미 살펴보았습니다.
useReducer Hook
useReducer는 useState보다 좀 더 복잡한 상황에서 state를 사용할 수 있도록 컴포넌트와 state의 업데이트 로직을 서로 분리시켜 관리할 수 있습니다.
useReducer 문법
const [state, dispatch] = useReducer(reducer, initialArg, init?)
useReducer의 첫 번째 인수는 reducer 함수를 전달 받으며, 두 번째 인수는 해당 reducer의 기본값을 전달 받습니다. 그리고 현재 state 값과 action을 발생시키는 dispatch 함수를 반환합니다.
useReducer가 반환하는 dispatch 함수를 사용하면 state를 다른 값으로 업데이트하고 리렌더링하도록 설정할 수 있습니다. 이때 dispatch 함수에는 인수로 action 값을 전달해야 합니다.
다음 예제는 버튼을 클릭하면 화면의 숫자가 증가하는 카운터 예제를 useState가 아닌 useReducer로 구현한 예제입니다.
예제(Counter.js)
import { useReducer } from "react";
// 컴포넌트와 분리된 state 업데이트 로직
const reducer = (state, action) => {
if (action.type === "increment") {
return {
count: state.count + 1
};
}
};
const Counter = () => {
// reducer 함수와 count의 기본값을 0으로 전달하여 state를 생성함
const [state, dispatch] = useReducer(reducer, { count: 0 });
return (
<div>
<h1>State 값 : {state.count}</h1>
{/* dispatch 함수에 action.type값으로 'increment'를 전달하여 리렌더링시킴 */}
<button onClick={() => dispatch({ type: "increment" })}>1씩 증가</button>
</div>
);
};
export default Counter;
useReducer를 사용했을 때 가장 큰 장점은 컴포넌트에서 state 업데이트 로직을 컴포넌트 외부로 분리시킬 수 있다는 점입니다.
reducer에 대한 개념은 이후 Redux를 살펴보면서 좀 더 자세히 알아볼 것입니다. 따라서 reducer 부분이 너무 어렵게 느껴진다면 우선은 건너뛰고 Redux 수업을 공부한 후에 다시 살펴보는 것을 권합니다.