TIL 30. Redux toolkit

isk·2022년 12월 11일
0

TIL

목록 보기
83/122
post-custom-banner

리덕스 툴킷에 대해 알아보고, 저번에 배운 내용에 적용을 해봤다.

Redux Store

툴킷을 적용하기 전의 store의 코드는 아래와 같다.

// configStore.js

import {createStore} from "redux";
import {combineReducers} from "redux";
import counter from "../modules/counter";



// 여러개의 리듀서를 하나로 모은다.
const rootReducer = combineReducers({
  counter: counter,
});

// 만든 리듀서를 통해 store를 생성.
const store = createStore(rootReducer);

// 생성한 리듀서를 export(내보낸다.)
export default store;

툴킷을 적용한 코드는 아래와 같다.

// configStore.js

import {configureStore} from "@reduxjs/toolkit";
import counter from "../modules/counters";

// 만든 리듀서를 통해 store를 생성.
const store = configureStore({reducer: counter});

// 생성한 리듀서를 export(내보낸다.)
export default store;

configureStore를 사용해서 한 번에 관리할 수 있다.

const store = configureStore({reducer: counter});

리듀서가 여러개라면 export한 함수를 reducer 부분에 더 추가하면된다.
아래처럼.

const store = configureStore({
  reducer: {
    counter: counter, 
    counter2: counter2
  }
});

또는

const store = configureStore({
  reducer: {
    counter, 
    counter2
  }
});

물론 import, export는 필수다.


Redux Module

툴킷을 적용하기 전의 코드는 아래와 같다.

// counter.js

// Action Value
const ADD_NUMBER = "ADD_NUMBER";
const DEL_NUMBER = "DEL_NUMBER";

// Action Creator
export const addNumber = (payload) => {
  return {
    type: ADD_NUMBER,
    payload: payload,
  };
};

export const delNumber = (payload) => {
  return {
    type: DEL_NUMBER,
    payload: payload,
  };
};

// Initial State
const initialState = {
  number: 0,
};

// Reducer
const counter = (state = initialState, action) => {
  switch (action.type) {
    case ADD_NUMBER:
      return {
        number: state.number + action.payload,
      };
    case DEL_NUMBER:
      return {
        number: state.number - action.payload,
      };
    default:
      return state;
  }
};

// export default reducer
export default counter;

툴킷은 적용한 코드는 아래와 같다.

// counters.js
import {createSlice} from "@reduxjs/toolkit";

// Action Creator
	// 비어있음

// Initial State
const initialState = {
  number: 0,
};

// Reducer

const counter = createSlice({
  name: "counter",
  initialState,
  reducers: {
    addNumber: (state, action) => {
      state.number = state.number + action.payload;
    },
    deleteNumber: (state, action) => {
      state.number = state.number - action.payload;
    },
  },
});

// export default reducer
export const counterActions = counter.actions;
export default counter.reducer;

기존 코드에서의 Action Creator 부분이 Reducer에 들어갔다!
Action Value 부분도 필요없어졌다.

만약 initialState가 number말고도 addName 같은 데이터를 받는다면,
아래처럼 initialState에 다른 값을 넣고, 아래 리듀서 addNumber 부분에
state.addName = state.addName = action.payload.name; 을 넣는 것으로 데이터를 저장할 수 있다.

// counters.js
import {createSlice} from "@reduxjs/toolkit";

// Action Creator
	// 비어있음

// Initial State
const initialState = {
  number: 0,
  addName : '',
};

// Reducer

const counter = createSlice({
  name: "counter",
  initialState,
  reducers: {
    addNumber: (state, action) => {
      state.number = state.number + action.payload;
      state.addName = state.addName = action.payload.name;
    },
    deleteNumber: (state, action) => {
      state.number = state.number - action.payload;
    },
  },
});

// export default reducer
export const counterActions = counter.actions;
export default counter.reducer;

Redux Dispatch

아래는 툴킷 적용 전 코드다.

// src/App.js

import React, {useState} from "react";
import {useSelector, useDispatch} from "react-redux";
import {addNumber, delNumber} from "./redux/modules/counter";

const App = () => {
  const [number, setNumber] = useState(0);
  const globalNumber = useSelector((state) => state.counter.number);
  const dispatch = useDispatch();
  const onChangeHandler = (event) => {
    setNumber(Number(event.target.value));
  };
  const onClickAddNumberHandler = () => {
    dispatch(addNumber(number));
  };
  const onClickDelNumberHandler = () => {
    dispatch(delNumber(number));
  };
  console.log(number);
  return (
    <div>
      {globalNumber}
      <input onChange={onChangeHandler} type="number" />
      <button onClick={onClickAddNumberHandler}>더하기</button>
      <button onClick={onClickDelNumberHandler}>빼기</button>
    </div>
  );
};

export default App;

아래는 툴킷 적용 후의 코드다.

// src/App.js

import React, {useState} from "react";
import {useSelector, useDispatch} from "react-redux";
import {counterActions} from "./redux/modules/counters";

const App = () => {
  const [number, setNumber] = useState(0);
  const globalNumber = useSelector((state) => state.number);
  const globalName = useSelector((state) => state.addName);
  const onChangeHandler = (event) => {
    setNumber(Number(event.target.value));
  };

  const dispatch = useDispatch();

  const onClickAddNumberHandler = () => {
    dispatch(counterActions.addNumber({name: "kim", num: number}));
  };
  const onClickDelNumberHandler = () => {
    dispatch(counterActions.deleteNumber(number));
  };

  return (
    <div>
      {globalNumber} {globalName}
      <input onChange={onChangeHandler} type="number" />
      <button onClick={onClickAddNumberHandler}>더하기</button>
      <button onClick={onClickDelNumberHandler}>빼기</button>
    </div>
  );
};

export default App;

payload로 객체를 주는 것으로 name과 num을 저장시켰다.


확실히 리듀서 안에 다 때려넣으니 편한 것 같다.
리엑트로 만들던 사이드 프로젝트를 파이어베이스 9버전으로 리팩토링하고,
다시 그걸 redux를 적용한 것으로 리팩토링 했었는데,
이젠 툴킷을 적용한 redux로 리팩토링 해야겠다 ㅎㅎㅎㅎㅎㅎㅎㅎ ㅜㅜ

post-custom-banner

0개의 댓글