상태관리란?
React에서 상태 관리란 컴포넌트의 상태를 관리하고 업데이트하는 것을 말한다. React는 컴포넌트 기반 라이브러리기 때문에 컴포넌트 간의 상태 전달이 필요할 때 상태 관리가 중요한 역할을 한다.
상태 관리 방법 중 가장 기본적인 방법은 React의 내장 상태 관리 기능인 useState 가 사용된다. useState는 대표적인 훅 함수 중 하나다. 그러나 useState는 단순 상태관리나 작은 프로젝트에 적합하며 규모가 크고 복잡한 프로젝트 같은 경우에는 사용함에 불편함이 있다.
Redux와의 차이점 그리고 장점.
- Redux Toolkit은 createSlice라는 함수를 제공하여 리듀서와 액션을 한 번에 생성하도록 한다.
- Redux에서는 반복적인 작업이 발생했는데, 이를 줄여줌.
- Redux Toolkit은 불변성을 유지하면서 상태를 간편하게 업데이트할 수 있는 immer 라이브러리를 내장하고 있다.
- 객체 구조 분해 할당을 할 필요 없이 직접적으로 state 값을 수정할 수 있게 됨.
Slice 개념
액션과 리듀서를 하나의 패키지로 묶어주는 기능이다. Slice를 생성할 때에는 초기 상태, 액션과 관련된 리듀서 함수를 정의해야 한다.
- 사용하지 않을 때
const INCREMENT = 'counter/increment';
const DECREMENT = 'counter/decrement';
function increment() {
return { type: INCREMENT };
}
function decrement() {
return { type: DECREMENT };
}
const initialState = {
count: 0
};
function counterReducer(state = initialState, action) {
switch (action.type) {
case INCREMENT:
return { ...state, count: state.count + 1 };
case DECREMENT:
return { ...state, count: state.count - 1 };
default:
return state;
}
}
- 사용할 때
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: { count: 0 },
reducers: {
increment: state => {
state.count += 1;
},
decrement: state => {
state.count -= 1;
}
}
});
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
예시 코드처럼 Redux-Tookit을 사용하면 매우 깔끔하게 코드를 작성할 수 있다. createSlice를 사용하여 Slice를 만들어 주고, 이름과 초기값, 리듀서를 설정해주면 된다.
Recoil
Facebook에서 개발된 React 상태 관리 라이브러리로, React 애플리케이션의 상태를 효율적으로 관리하기 위한 솔루션이다.
컴포넌트 간의 상태 공유와 관리를 위해 상태를 Atoms와 Selectors로 구성한다.
- Atoms : Recoil의 핵심 개념으로, 애플리케이션의 상태를 나타냄. atom 함수를 사용하여 정의되며, atom 함수는 상태의 초기값을 인자로 받음.
- Selectors : Atoms나 다른 Selectors를 기반으로 계산된 값. selector 함수를 사용하여 정의되며, selector 함수는 읽을 상태와 상태를 계산하는 함수를 인자로 받음
- 상태 관리 방식: Redux는 중앙 집중식 저장소에 상태를 저장하고 관리하는 반면, Recoil은 컴포넌트 내부에 상태를 저장하고 관리.
- 불변성 유지: Redux는 불변성을 강조하며 상태의 변경을 예측 가능한 방식으로 관리하지만, Recoil은 기본적으로 불변성을 유지하지 않음.
- (하지만 Recoil의 Atoms은 내부적으로 Immutable 데이터 구조를 사용.)
코드 예시
import { atom, selector, useRecoilState, useRecoilValue } from 'recoil';
const countState = atom({
key: 'count',
default: 0,
});
const doubledCountState = selector({
key: 'doubledCount',
get: ({ get }) => {
const count = get(countState);
return count * 2;
},
});
function Counter() {
const [count, setCount] = useRecoilState(countState);
const doubledCount = useRecoilValue(doubledCountState);
const increment = () => {
setCount(count + 1);
};
const decrement = () => {
setCount(count - 1);
};
return (
<div>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
<p>Count: {count}</p>
<p>Doubled Count: {doubledCount}</p>
</div>
);
}
위의 코드에서 countState는 Atom으로 상태를 정의하고, doubledCountState는 Selector로 계산된 상태 값을 정의한다.
그리고 useRecoilState 훅을 사용하여 Atom의 상태 값을 읽고 업데이트하며, useRecoilValue 훅을 사용하여 Selector의 계산된 상태 값을 읽는다.
정리하기
이번에는 Redux-Tookit과 Recoil에 대해 알아보았다. React에서 상태관리는 매우 중요한 개념이다. 그렇기 때문에 그에 따른 상태관리 라이브러리들도 굉장히 중요한데, 이번에 공부를 해보았다.
둘 다 굉장히 생김새는 비슷하지만, 중앙 저장소라는 개념이 다르기 때문에 이를 유념할 필요는 있다. 각자의 장점이 있기 때문에 프로젝트의 형태에 맞는 라이브러리를 선택해서 사용하면 좋을 것 같다.