리덕스를 사용하면서 언급되는 3가지 문제점은 아래와 같다.
이러한 문제점들을 해결하고자 RTK이 만들어졌다고 한다.
// 🛠 createStore
import { createStore, applyMiddleware, compose } from 'redux';
import rootReducer from './reducers';
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
rootReducer,
composeEnhancers(applyMiddleware(thunk))
);
createStore
를 생성해야 했다.combineReducres
를 사용해 리듀서(Reducer)를 하나로 합쳐서 rootReducer
를 인자로 받는다.// ✨ configureStore
import { configureStore } from '@reduxjs/toolkit';
export const store = configureStore({
reducer: {
todos: todosReducer,
},
});
combineReducres
를 사용하지 않고, reducer 필드를 필수적으로 넣느다.// 🛠 action + action creator
import axios from 'axios';
const ADD_TODO = 'ADD_TODO';
export const addTodo = (value) => async (dispatch) => {
const response = await axios.post('http://localhost:5000/todos', {
value: value,
});
dispatch({ type: ADD_TODO, payload: response });
};
기존 리덕스에서는 액션과 액션 생성자 함수를 별도로 만들어야 했다.
// ✨ createAction
import { createAction } from '@reduxjs/toolkit';
const addTodo = createAction('ADD_TODO');
const reducer = (state = [], action) => {
switch (action.type) {
case addTodo.type:
return [
{
id: Date.now().toString(),
value: action.payload,
}, ...state];
default:
return state;
}
}
createAction
호출하면 하나의 객체 action
객체를 생성한다.action
객체는 type
,payload
속성을 가지고 있다.action
객체에 payload
를 사용하여 다른 값을 전달할 수 있다. // 🛠 reducer
import { createAction } from '@reduxjs/toolkit';
const addTodo = createAction('ADD_TODO');
const reducer = (state = [], action) => {
switch (action.type) {
case addTodo.type:
return [
{
id: Date.now().toString(),
value: action.payload,
}, ...state];
default:
return state;
}
}
type
을 찾을 때, switch
문을 사용했었다.
// ✨ createReducer
import { createAction, createReducer } from '@reduxjs/toolkit';
const addTodo = createAction('ADD_TODO');
const reducer = createReducer([], {
[addToDo]: (state, action) => {
state.push({ id: Date.now().toString(), value: action.payload });
}
})
createReducer
를 사용하면, immutable 관리까지 자동으로 관리해주는 유틸 함수이다.createReducer
의 key
의 값은 createAction
을 넣어서 사용한다.createSlice
는 앞서 언급한createAction
, createReducer
함수가 내부적으로 사용된다.name
속성에 따라서 리듀서와 그것에 상응하는 액션 생성자와 액션 타입을 자동으로 생성한다.// ✨ createSlice
import { createSlice, nanoid } from "@reduxjs/toolkit";
const todos = createSlice({
name: 'todos',
initialState: []
reducers: {
addTodo: (state, acion) => {
state.push({ id: nanoid(), value: acion.payload });
},
})
state
를 건드리지 않고 복사하여 새로운 배열을 생성하는 arr.map
, arr.filter
, arr.concat
등 과 같은 배열 함수를 사용해왔다.createReducer
, createSlice
함수는 불변성을 신경 쓰지 않아도 된다. 그 이유는 자동으로 불변성을 유지 Immer 라이브러리를 가지고 있기 때문이다.