2023.08.11 Redux Toolkit

이무헌·2023년 8월 11일
0

react

목록 보기
18/19
post-thumbnail

1.ReduxToolkit이란?

Redux Toolkit은 Redux를 더 효율적으로 개발할 수 있도록 도와주는 도구이다. 기존 redux는 reducer를 일일히 작성해줘야 했지만 redux toolkit은
createSlice와 createReducer와 같은 함수를 통해 상태와 리듀서를 쉽게 생성할 수 있게 해준다.특히, createAsyncThunk 함수를 제공하여 기존 redux보다 쉽게 비동기 액션을 관리할 수 있도록 도와준다.

2.사용법

간단하다. 먼저 initial state가 있는 slice를 생성한다.폴더이름은 features로 해줬다.

1.countSlice.js

//features 폴더
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import axios from "axios";
// createSlice메서드를 사용해서 create 함수를 가지고 있는 객체를 만듦
export const counterSlice = createSlice({
 // Slice 구분 이름
 name: "count",
 // 초기값
 initialState: { num: 0 },
 reducers: {
   add: (state,action) => {
     //받아올 값이 있다면 action.payload로
     // 이전 상태가 매개변수로 들어온다.
     state.num += 1;
   },
   remove: (state) => {
     state.num -= 1;
   },
 },
});

// 액션함수를 내보내서 dispatch로 전달해서 액션 발생시킬거임
export const { add, remove } = counterSlice.actions;

export const temp = createAsyncThunk("/temp", async () => {
 // axios
 const resp = await axios.get("http://localhost:8080/main");
 const { data } = resp;
 console.log(data);
 return data;
});

// createSlice메서드를 사용해서 create 함수를 가지고 있는 객체를 만듦
export const counterSlice2 = createSlice({
 // Slice 구분 이름
 name: "count2",
 // 초기값
 initialState: { num: 0, value: "나 상태" },
 reducers: {
   add2: (state) => {
     // 이전 상태가 매개변수로 들어온다.
     state.num += 1;
   },
   remove2: (state) => {
     state.num -= 1;
   },
 },
 //   비동기 처리는 여기에 작성해라
 extraReducers: (builder) => {
   // extraReducers 의builder 매개변수로 받고 케이스를 추가하는데
   // 상태의 케이스 추가 로딩중,완료,실패
   // 상태 케이스를 등록해준다.
   // builder.addCase() 케이스 추가
   // loading 중=> pendig일때
   builder.addCase(temp.pending, (state, action) => {
     state.value = "로딩중임";
   });
   // 다 받아왔을 때 =>fulfilled
   builder.addCase(temp.fulfilled, (state, value) => {
     state.value = "완료";
     state.num+=1
   });
   // 실패했을 때 케이스
   builder.addCase(temp.rejected, (state, action) => {
     state.value = "실패";
   });
 },
});

// 액션함수를 내보내서 dispatch로 전달해서 액션 발생시킬거임
export const { add2, remove2 } = counterSlice2.actions;

reducer의 두번째 매개변수는 action이 들어간다. 기존 redux와 똑같이 action.payload로 값을 가져오면 된다

당연하지만 action,reducer가 store도 존재한다.

2.store.js

import { configureStore } from "@reduxjs/toolkit";
import { counterSlice, counterSlice2 } from "../features/countSlice";
// 저장소 생성
export const store = configureStore({
  reducer: {
    count: counterSlice.reducer,
    count2: counterSlice2.reducer,
  },
});

configureStore로 저장소를 생성한다. reducer라는 객체 안에서 만든 각각의 reducer를 value로 할당한다.

이제 dispatch로 state를 변경해보자
3.dispatch.js


import React from "react";
import { produce } from "immer";
import { add, remove, add2, remove2, temp } from "./src/features/countSlice";
import { useDispatch, useSelector } from "react-redux";

const App = () => {
  const dispatch = useDispatch();
  const num = useSelector((state) => state.count.num);
  const num2 = useSelector((state) => state.count2.num);
  const value = useSelector((state) => state.count2.value);
  const state = {
    value: 0,
    arr: [],
  };
  // 값이 변해도 바뀐것을 react에선 감지를 못하기 때문에
  // 불변성을 지킨다라는 내용이
  // 기존값을 직접 수정하지 않고 새로운 값을 만들어 내는 것
  const nextState = produce(state, (dra) => {
    // state를 새로 가져온거임
    // 즉,기존 객체를 가져와 복사를 한 상태이기 때문에 우리가 새로운 객체를 생성하면 nextState에 반환됨
    // {...state,value:state.value+1}
    dra.value += 1;
    console.log(dra.value);
    dra.arr.push("쉬는시간");
  });
  console.log(state);
  console.log(nextState);

  return (
    <div>
      <div>
        숫자:{num}
        <button
          onClick={() => {
            dispatch(add());
          }}
        >
          +
        </button>
        <button
          onClick={() => {
            dispatch(remove());
          }}
        >
          -
        </button>
      </div>
      <div>
        로딩 완료 여부:{value} <br/>
        숫자2:{num2}
        <button onClick={()=>{
          dispatch(temp())
        }}>포켓몬 정보 가져오기</button>
        <button
          onClick={() => {
            dispatch(add2());
          }}
        >
          +
        </button>
        <button
          onClick={() => {
            dispatch(remove2());
          }}
        >
          -
        </button>
      </div>
    </div>
  );
};

export default App;

// react에서 불변성을 유지하는 코드를 쉽게 작성할 수 있게 도와주는 라이브러리
// npm i immer

// react에서 기본적으로 부모에서 받은 props를 내부의 상태인 state가 변경되었을 때 다시 리렌더링을 하는
// 이 때도 props와 state의 변경을 불변성을 이용해서 감지한다.
// 객체의 참조를 복사한다는 점을 이용해서 비교하는 얕은 비교를 통해 변경이 이루어진다.

3.느낀점

프로젝트 기간이라 기존 라이브러리,내부 컴포넌트를 사용하다 redux toolkit이 굉장히 편리해서 따로 정리하였다. action,reducer,store의 삼각관계를 정확히 이해해야 편리하게 사용할 수 있다는 점에서 redux의 기초가 얼마나 중요한지 알 수 있었다.

profile
개발당시에 직면한 이슈를 정리하는 곳

1개의 댓글

comment-user-thumbnail
2023년 8월 11일

잘 봤습니다. 좋은 글 감사합니다.

답글 달기

관련 채용 정보