과거 프로그래밍 자료들/React

(next.js + redux toolkit 시리즈 3) reduxjs/toolkit

평부 2022. 10. 12. 16:55

 

 

출처 : https://www.youtube.com/watch?v=bpbLq6NxIm8&t=38 

 

* 출처 : https://github.com/mayank7924/nextjs-with-redux/tree/redux-toolkit

▶ components는 깃허브를 참고하는 게 좋습니다

 

GitHub - mayank7924/nextjs-with-redux

Contribute to mayank7924/nextjs-with-redux development by creating an account on GitHub.

github.com

 

출처 : https://redux-toolkit.js.org/api/createslice

 

createSlice | Redux Toolkit

 

redux-toolkit.js.org

 

 

react-redux is just a library which enables you to use the dispatch and get state value functions inside your react components.

 

so using this library(react-redux) will be able to access our state values and mutate them on the client side 

 

react-redux는 반응 구성 요소 내에서 디스패치 및 상태 값 가져오기 기능을 사용할 수 있게 해주는 라이브러리입니다.

 

따라서 이 라이브러리(react-redux)를 사용하면 상태 값에 액세스하고 클라이언트 측에서 변경할 수 있습니다.

 

 

next-redux-wrapper acts as a wrapper around our main redux store.


so that it's next.js friendly

 

next-redux-wrapper는 메인 redux 스토어를 감싸는 래퍼 역할을 합니다.

 

next.js에 친화적입니다

 

wrapper의 예시

[_app.js]

▶ wrapper로 App 함수를 감쌈

import { wrapper } from "../store/store";

const App = ({ Component, pageProps }) => {
  return <Component {...pageProps} />;
};

export default wrapper.withRedux(App);

 

 

* reduxjs/toolkit의 장점

▶ (next.js + redux toolkit 시리즈 2)처럼 action, reducer를 분리하지 않아도 됨

▶ createWrapper, HYDRATE가 동시에 사용 됨

 

 

reduxjs/toolkit 사용 전(createStore 사용)

action, reducer가 따로 만듦

 

 

[store.js]

▶ createStore, applyMiddle, combineReducers, composeWithDevTools가 사용됨

import { createStore, applyMiddleware, combineReducers } from "redux";
import { HYDRATE, createWrapper } from "next-redux-wrapper";
import { composeWithDevTools } from "redux-devtools-extension";

import users from "./users/reducer";
import counter from "./counter/reducer";

const rootReducer = combineReducers({
  counter,
  users,
});

const masterReducer = (state, action) => {
  if (action.type === HYDRATE) {
    const nextState = {
      ...state,
      counter: {
        count: state.counter.count + action.payload.counter.count,
      },
      users: {
        users: [
          ...new Set([...action.payload.users.users, ...state.users.users]),
        ],
      },
    };
    return nextState;
  } else {
    return rootReducer(state, action);
  }
};

const initStore = () => {
  return createStore(masterReducer, composeWithDevTools(applyMiddleware()));
};

export const wrapper = createWrapper(initStore);

 

 

reduxjs/toolkit 사용 후

counter, users 폴더 대신 counterSlice, usersSlice로 만듦

 

 

[store.js]

▶ combineReducers, configureStore 사용

▶ action은 store에 들어감

import { combineReducers, configureStore } from "@reduxjs/toolkit";
import { createWrapper, HYDRATE } from "next-redux-wrapper";
import users from "./usersSlice";
import counter from "./counterSlice";

const rootReducer = combineReducers({
  users,
  counter,
});

const masterReducer = (state, action) => {
  if (action.type === HYDRATE) {
    const nextState = {
      ...state,
      counter: {
        count: state.counter.count + action.payload.counter.count,
      },
      users: {
        users: [...action.payload.users.users, ...state.users.users],
      },
    };
    return nextState;
  } else {
    return rootReducer(state, action);
  }
};

export const makeStore = () =>
  configureStore({
    reducer: masterReducer,
  });
export const wrapper = createWrapper(makeStore, { debug: true });

 

 

[counterSlice.js]

▶ reducers가 들어감(reduxjs/toolkit 사용 전에는 action, reducer가 따로 분리됨)

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  count: 0,
};

export const counterSlice = createSlice({
  name: "counter",
  initialState,
  reducers: {
    increment: (state) => {
      state.count = state.count + 1;
    },
  },
});

export const { increment } = counterSlice.actions;

export default counterSlice.reducer;

 

[usersSlice.js]

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  users: [],
};

export const usersSlice = createSlice({
  name: "users",
  initialState,
  reducers: {
    addUser: (state, action) => {
      state.users = [...state.users, action.payload];
    },
  },
});

export const { addUser } = usersSlice.actions;

export default usersSlice.reducer;

 

 

[결과]

01