Redux Toolkit

Hoon·2022년 12월 28일
0

React

목록 보기
10/15
post-thumbnail

Redux Toolkit

Redux Toolkit : Redux ToolkitRedux 를 더 사용하기 쉽게 만들기 위해 Redux 에서 공식 제공하는 개발도구이다.

기존Redux 에서는 아래와 같은 3가지 문제점이 있었다.

  • 복잡한 Redux 스토어 구성
  • 많은 패키지의 필요성
  • 한 작업 시 필요한 수많은 코드양

위의 문제점을 Redux Toolkit 을 사용하여 해결하면 좀 더 효율적인 Redux 개발이 가능해진다.


Redux Toolkit 사용하기

먼저, createSlice 를 통하여 reduceraction포함한 객체를 생성한다.

// 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 }))

Redux Toolkit을 통한 비동기처리

먼저, 비동기 처리를 위해 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())
profile
개발자 Hoon입니다

0개의 댓글