Redux Toolkit

채희태·2022년 8월 26일
0

리덕스 툴킷

기존의 리덕스가 아닌 리덕스 툴킷을 사용하는 이유는 무엇일까?

  • 기존의 리덕스는 환경설정시 작성해야 하는 코드와 사용할 파일이 너무 많아 복잡하다.
  • 리덕스 툴킷은 필요한 모듈을 담고 있는 도구모음과 같다.
  • 리덕스 툴킷이 담고 있는 createAsyncThunk로 비동기 처리를 비교적 쉽게 할 수 있다.
  • 리덕스 툴킷은 immer 패키지를 갖고 있으므로 불변성을 지켜가며 작성할 필요가 없다.

설치 방법은 다음과 같다.

이미 앱이 존재할 때.
npm i @reduxjs/toolkit
CRA로 앱을 설치할 때.
npx create-react-app my-app --template redux
npx create-react-app my-app --template redux-typescript

장바구니 예제를 통해 리덕스 툴킷 사용법을 익혀본다.

slice

slice는 createSlice로 생성하며 createSlice의 인자로 들어가는 객체는
1. name (이름)
2. initailState (초기값)
3. reducers (리듀서 함수) -> action creator 생성.
로 구성된다.

사용법
src/redux/modules/cartSlice.js

import { createSlice } from '@reduxjs/toolkit'

const cartSlice = createSlice({
  name: "cart",
  initialState: [],
  reducers: {
    addReducer: (state, action) => {
      state = state.push(action.payload)
    },
  },
})
 
// dispatch로 쉽게 접근하기 위해 구조분해 할당.
export const { addReducer } = cartSlice.actions
export default cartSlice

store

store는 configureStore로 생성하며 여러 slice들을 한데 모아주는 역할을 한다.
reducer을 reducers로 착각하지 않도록 주의해야 한다.

사용법
src/redux/configureStore.js

import { configureStore } from '@reduxjs/toolkit'
import cartSlice from '../redux/modules/cartSlice'

const rootReducer = combineReducers({
  cart: cartSlice.reducer,
})

const store = configureStore({
  reducer: rootReducer,
})

export default store

연결하기

리액트 프로젝트와 생성한 store를 연결하여야 한다.
이를 위해 index.js에서 store를 불러와 provider로 하위컴포넌트로 뿌려준다.

사용법

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

import { Provider } from "react-redux";
import store from "./redux/configStore";

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

사용하기

useSelector

useSelector를 이용해 store의 데이터를 조회할 수 있다.

사용법

import { useSelector } from 'react-redux'

const cart = useSelector(state => state.cart)

useDispatch

리듀서에서 생성한 action creator를 발생시킬 수 있다.
action creator의 인자로 값을 넣으면 이를 reducer에서 action payload로 사용할 수 있다.

사용법

import { useDispatch } from 'react-redux'
const dispatch = useDispacth()

dispatch(addReducer(product))

리덕스 툴킷 비동기

리덕스 툴킷에서 따로 미들웨어를 설정할 필요 없이 비동기 처리를 해주는 기능인 createAsyncThunk를 사용할 수 있다.

상품 목록 예제를 통해 익혀본다.

slice

  1. createAsyncThunk
  • 첫번째 인자로 action의 이름을, 두번째 인자로 비동기 처리를 할 함수를 입력한다.
  1. createSlice
  • extraReducers에서 pending, fullfilled, rejected 세 가지 경우의 처리 결과를 넣어준다.

src/redux/modules/productsSlice.js

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'

//asyncThunk 생성
export const loadProducts = createAsyncThunk(
  //action 이름
  "load/products"
  //비동기 처리
  async () => {
    const res = await axios.get('http://localhost:5008/products')
    const products = res.json()
    //action의 payload로 리턴
    //products === action.payload
    return products
  }
)  
//slice 생성
const productsSlice = createSlice({
  name: products,
  intialState: {
    list: [],
    status: null,
  },
  extraReducers: {
    [loadProducts.pending]: (state, action) => {
      state.status = 'pending'
    },
    [loadProducts.fullfilled]: (state, action) => {
      state.list = [...action.payload]
      state.status = 'fullfilled'
    },
    [loadProducts.rejected]: (state, action) => {
      state.status = 'rejected'
    },
  },
})

export default productsSlice.reducer

store

store는 configureStore로 생성하며 여러 slice들을 한데 모아주는 역할을 한다.
reducer을 reducers로 착각하지 않도록 주의해야 한다.

사용법
src/redux/configureStore.js

import { configureStore } from '@reduxjs/toolkit'
import cartSlice from '../modules/cartSlice'
import productSlice from '../modules/productsSlice'

const store = configureStore({
  reducer: {
    cart: cartSlice,
    products: productsSlice,
  },
})

export default store

사용하기

useDispatch

createAsyncThunk 함수를 dispatch해준다.

//createAsyncThunk로 생성한 비동기 처리 함수
import { loadProducts } from "./redux/modules/productsSlice";
import { useDispatch, useSelector } from "react-redux";
import { useEffect } from "react";

const App = () => {
  const productList = useSelector(state => state.products.list)
  const dispatch = useDispatch()
  
  useEffect(() => {
    dispatch(loadProducts())
  }, [])
}
profile
기록, 공부, 활용

0개의 댓글