nextjs - redux toolkit
npx create-next-app@latest --typescript
npm i @reduxjs/toolkit
npm i react-redux
npm i next-redux-wrapper
npm i redux-logger --save-dev # 필요한 경우에 설치
├── README.md
├── next.config.js
├── node_modules
├── package-lock.json
├── package.json
├── pages
├── public
├── store
│├── modules
││ ├── counter.js (리듀서 모듈)
││ └── index.js (리듀서 모듈 통합)
│└── index.js (store 생성 && wrapper 생성)
└── styles
store/modules/conter.js
import { createSlice } from '@reduxjs/toolkit';
const initialState = { value: 0 }; // 초기 상태 정의
const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: state => { state.value += 1 },
decrement: state => { state.value -= 1 },
},
});
export const { increment, decrement } = counterSlice.actions; // 액션 생성함수
export default counterSlice.reducer; // 리듀서
다른 컴포넌트/모듈 내에서 사용하기 위해 정의한 리듀서와 액션 생성함수를 export한다.
● createSlice: action과 reducer를 한 번에 정의한다.
● createAction + createReducer = createSlice
● 비동기적인 리듀서 함수를 정의하고자 할 땐 객체의 프로퍼티로 extraReducers객체를 추가한다.
store/modules/index.js
import { combineReducers } from "@reduxjs/toolkit";
import { HYDRATE } from "next-redux-wrapper";
import counter from './counter';
const reducer = (state, action) => {
if (action.type === HYDRATE) {
return { ...state, ...action.payload };
}
return combineReducers({
counter,
// 여기에 추가
})(state, action);
};
export default reducer;
modules 내에서 정의한 모듈들을 합쳐주는 역할을 한다.
if (action.type === HYDRATE): SSR작업 수행 시 HYDRATE라는 액션을 통해서
서버의 스토어와 클라이언트의 스토어를 합쳐주는 작업을 수행한다.
combineReducers: 함수명 그대로 정의한 리듀서 모듈들을 결합하는 역할을 한다.
리듀서 모듈(slice)을 추가할 때마다 combineReducers함수의 인자로 전달되는 객체 내부에 추가해준다.
store/index.js
import { configureStore } from '@reduxjs/toolkit';
import { createWrapper } from "next-redux-wrapper";
import logger from 'redux-logger';
import reducer from './modules';
const makeStore = (context) => configureStore({
reducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(logger),
devTools: process.env.NODE_ENV !== 'production',
});
export const wrapper = createWrapper(makeStore, {
debug: process.env.NODE_ENV !== 'production',
});
스토어를 생성하는 함수를 정의하고, 이를 인자로 wrapper HOC를 만든다.
configureStore: store를 생성한다.
redux-toolkit은 devTools 등의 미들웨어들을 기본적으로 제공한다.
여기에 사용하고 싶은 미들웨어가 있다면 추가로 정의해준다.
위의 코드에선 logger를 추가해줬다.
createWrapper: wrapper를 생성한다.
지금까지 리듀서 모듈 만들기 -> 리듀서 모듈 합치기 -> 스토어 생성의 과정을 거쳤다.
이제 최종적으로 wrapper에 스토어를 바인딩해주면 된다.
pages/_app.js
import '../styles/globals.css';
import { wrapper } from "../store";
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default wrapper.withRedux(MyApp);
wrapper의 withRedux HOC로 App컴포넌트를 감싸준다.
이제 각 페이지에서 getStaticProps, getServerSideProps 등의
함수 내에서 스토어 접근이 가능해진다.
작동을 확인하기 위해 다음과 같이 pages 디렉토리 내에
counter.js(counter.jsx)를 작성해보자.
pages/counter.js
import { useCallback } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import * as counterActions from '../store/modules/counter';
export default function Test() {
const dispatch = useDispatch();
const value = useSelector(({ counter }) => counter.value);
const plus = useCallback(({ value }) => {
dispatch(counterActions.increment({ value }));
}, [dispatch]);
const minus = useCallback(({ value }) => {
dispatch(counterActions.decrement({ value }));
}, [dispatch]);
return (
<div>
<h1>Counter</h1>
<button onClick={() => minus({ value })}>-</button>
<span>{value}</span>
<button onClick={() => plus({ value })}>+</button>
</div>
);
}
Author And Source
이 문제에 관하여(nextjs - redux toolkit), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@byunghyun/nextjs-redux-toolkit저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)