RTK는 Redux Toolkit의 패키지로, React와 Redux를 함께 사용하는 프로젝트에서 Redux를 더 쉽게 사용할 수 있도록 도와줌.
RTK의 다양한 기능을 활용해 Redux 코드를 더욱 간결하고 효율적으로 작성 가능.
$ yarn add react-redux
$ yarn add @reduxjs/toolkit
✦ 기존 Redux 코드:
const ADD_TODO = "ADD_TODO";
export const addTodo = (payload) => {
return {
type: ADD_TODO,
payload: payload,
};
};
✦ RTK 코드:
import { createSlice } from '@reduxjs/toolkit';
createSlice 가 자동으로 필요한 액션 타입과 생성자를 만들어줍니다. 따라서 별도로 ADD_TODO 와 같은 액션 타입을 정의할 필요가 없습니다.✦ 기존 Redux 코드:
const initialState = [
{
id: 1,
title: "react를 배워봅시다.",
},
{
id: 2,
title: "redux를 배워봅시다.",
},
];
const todos = (state = initialState, action) => {
switch (action.type) {
case ADD_TODO:
return [...state, action.payload];
default:
return state;
}
};
✦ RTK 코드:
const todosSlice = createSlice({
name: 'todos',
initialState: [
{
id: 1,
title: "react를 배워봅시다.",
},
{
id: 2,
title: "redux를 배워봅시다.",
},
],
reducers: {
addTodo: (state, action) => {
state.push(action.payload);
},
},
});
초기 상태(initialState): RTK에서도 동일하게 초기 상태를 설정하지만, createSlice 안에 initialState를 포함합니다.
리듀서 정의: 기존 Redux에서는 switch 문을 사용하여 각 액션 타입에 따라 상태를 업데이트했습니다. RTK에서는 createSlice의 reducers 객체 안에 각각의 리듀서를 함수 형태로 정의합니다. 예를 들어, addTodo 리듀서에서 state.push(action.payload)로 새로운 할 일을 추가할 수 있습니다.
불변성 관리: RTK에서는 내부적으로 immer 라이브러리를 사용하여 불변성을 자동으로 관리해줍니다. 그래서 state.push() 같은 코드가 가능해집니다.
🔍 RTK와 immer 라이브러리
Redux Toolkit(RTK)에서는 immer라는 라이브러리가 내부적으로 사용됩니다. immer는 불변성을 유지하면서도 더 직관적이고 간결한 코드를 작성할 수 있도록 도와줍니다.
immer의 역할: immer는 상태 객체를 "임시적으로" 변경할 수 있는 형태로 만들어줍니다. 이 상태에서 변경된 내용을 바탕으로 새로운 불변 상태를 자동으로 생성해 줍니다.
상태 업데이트가 직관적이고 간결해지며, spread 연산자(...)나 깊은 복사를 수동으로 처리할 필요가 없습니다.
✦ 기존 Redux 코드:
export const addTodo = (payload) => {
return {
type: ADD_TODO,
payload: payload,
};
};
export default todos;
✦ RTK 코드:
export const { addTodo } = todosSlice.actions;
export default todosSlice.reducer;
액션 내보내기: RTK에서는 todosSlice.actions 객체에서 자동으로 생성된 액션을 구조 분해 할당(destructuring) 방식으로 내보냅니다. addTodo는 기존 Redux에서 export const addTodo = ...로 내보냈던 것과 동일한 기능을 합니다.
리듀서 내보내기: 기존 Redux에서 todos 리듀서를 내보냈던 것과 마찬가지로, RTK에서는 todosSlice.reducer를 내보냅니다.
✦ 기존 Redux 코드:
import { combineReducers, createStore } from 'redux';
import todos from '../modules/todos';
const rootReducer = combineReducers({
todos,
});
const store = createStore(rootReducer);
export default store;
✦ RTK 코드:
import { configureStore } from '@reduxjs/toolkit';
import todosReducer from '../modules/todos';
const store = configureStore({
reducer: {
todos: todosReducer,
},
});
export default store;
스토어 설정: 기존 Redux에서는 combineReducers와 createStore를 사용해 스토어를 설정했습니다. RTK에서는 configureStore라는 함수를 사용하여 스토어를 더 간단하게 설정할 수 있습니다.
자동화된 설정: RTK의 configureStore는 기본적으로 Redux DevTools, thunk 미들웨어 등을 자동으로 포함하여 설정해 줍니다. 덕분에 설정이 더 간편해집니다.
🔍 내부적으로 쓰이는 함수
RTK의 createSlice: 리듀서와 액션을 정의하는 함수로, 내부적으로 immer의 produce 함수를 사용해 불변성을 자동으로 관리합니다.
immer의 produce: RTK의 리듀서에서 상태를 직접 변경하는 것처럼 보이게 하면서도, 실제로는 새로운 불변 상태를 생성하는 함수입니다.