Redux Toolkit
:Redux Toolkit
은Redux
를 더 사용하기 쉽게 만들기 위해Redux
에서 공식 제공하는 개발도구이다.
기존의 Redux
에서는 아래와 같은 3가지 문제점이 있었다.
Redux
스토어 구성위의 문제점을 Redux Toolkit
을 사용하여 해결하면 좀 더 효율적인 Redux
개발이 가능해진다.
먼저, createSlice
를 통하여 reducer와 action을 포함한 객체를 생성한다.
// user.js
import { createSlice } from "@reduxjs/toolkit";
export const userSlice = createSlice({
// slice 이름
name: 'userState',
// 초기 값
initialState: {
id: '',
name: ''
},
// 리듀서
reducers: {
handleUserUpdate: (state, action) => {
return { ...action.payload };
}
}
})
export const { handleUserUpdate } = userSlice.actions
생성한 slice 객체들을 불러와 combineReducers
를 통하여 여러개의 reducer
를 결합하고
configureStore
를 통하여 store를 생성해준다 !
// index.js
import { combineReducers, configureStore } from "@reduxjs/toolkit";
import { dataSlice } from "./modules/data";
import { userSlice } from "./modules/user"
// reducer 결합 (여러 reducer를 하나의 store에 저장해주는 역할)
const rootReducer = combineReducers({
data: dataSlice.reducer,
user: userSlice.reducer
});
// store 생성 (createStore와 다르게 default로 devTools를 제공)
const store = configureStore({ reducer: rootReducer })
export default store;
이렇게 설정한 store
는 아래와 같이 action
을 import 해서 사용할 수 있다.
// Home.js
import { useDispatch } from "react-redux";
import { handleUserUpdate } from "../store/modules/user";
const dispatch = useDispatch();
dispatch(handleUserUpdate({ ...form }))
먼저, 비동기 처리를 위해 axios
를 설치해주고 아래와같이 간단한 설정을 해주었다.
import axios from "axios"
const baseURL = `${process.env.REACT_APP_BASE_URL}`
const api = axios.create({
baseURL: baseURL,
timeout: 3000,
headers: {
'Content-Type': 'application/json',
}
})
export default api
아래의 코드는 Redux Toolkit
을 사용하여 비동기 처리를 작성한 코드이다.
createAsyncThunk
를 통하여 외부에서 비동기 action
을 생성해주었고
extrReducers
를 통하여 비동기 작업 함수 처리를 한다.
// data.js
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import api from "../../apis/client"
// 매개변수 (thunk name, async function) 비동기 작업
export const asyncFetch = createAsyncThunk('data/asyncFetch', async () => {
const { data } = await api.get(`${process.env.REACT_APP_API_URL}`)
return data
})
export const dataSlice = createSlice({
// slice 이름
name: 'dataState',
// 초기 값
initialState: {
value: {},
loading: false,
error: null
},
// 리듀서
reducers: {},
/**
* extraReducers
* 외부에서 만들어진 action을 통해 현재 slice에서 사용하는
* initialState에 변경을 가하는 경우 처리받는 reducer
* (비동기 작업 함수 처리 등에 사용됨)
*/
extraReducers: (builder) => {
// 통신 중
builder.addCase(asyncFetch.pending, (state, action) => {
state.loading = true;
console.log('pending');
})
// 통신 성공
builder.addCase(asyncFetch.fulfilled, (state, action) => {
state.loading = false;
state.value = action.payload.datas;
console.log('success');
})
// 통신 실패
builder.addCase(asyncFetch.rejected, (state, action) => {
state.loading = false;
state.error = action.error;
console.log('reject');
})
}
})
이렇게 설정한 비동기 action
도 아래와 같이 간단하게 사용할 수 있다.
// Home.js
import { useDispatch } from "react-redux";
import { asyncFetch } from "../store/modules/data"
const dispatch = useDispatch();
dispatch(asyncFetch())