일반적인 React 처럼 사용하면 되지만 약간 다른 부분이 있어 정리해보았습니다.
우선 일반적인 React + Redux 사용법은
https://darrengwon.tistory.com/184?category=889133
https://darrengwon.tistory.com/556?category=889133
여기를 참고합시다.
차이점 1 ) 우선 Provier로 감쌀 최상위 컴포넌트는 page/_app.js 입니다. React 때 처럼 index.js가 없거든요.
차이점 2 ) Next에서는 store를 최상위 컴포넌트의 props에 가져와야 합니다. 그런데 _app.js에 있는 컴포넌트에 props가 존재할 수가 없죠. HOC을 이용해서 한번 감싸줘야 합니다. 다음 패키지(next-redux-wrapper)를 설치 한 후 감싸줍시다.
* next-redux-wrapper 5.0.0 버전기준입니다. 6버전 부터는 방식이 달라졌습니다. Next9.3 이후부터는 6버전을 사용하기를 권장하고 있습니다. 아무래도 6버전을 써야겠죠.
(https://github.com/kirill-konshin/next-redux-wrapper) 여기를 참고합시다.
npm i next-redux-wrapper
5버전 + getInitialProps
store에 enhancer도 가미했습니다.
import withRedux from "next-redux-wrapper";
import { createStore } from "redux";
import { Provider } from "react-redux";
import Rootreducer from "../reducers";
const MyApp = ({ Component, store }) => {
return (
<Provider store={store}>
<Component />
</Provider>
);
};
export default withRedux((initialState, options) => {
const middlewares = [];
const enhancer = compose(
applyMiddleware(...middlewares),
typeof window !== "undefined" &&
window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__()
);
const store = createStore(Rootreducer, initialState, enhancer);
return store;
})(MyApp);
어... 그런데 어느 순간 부터 legacy 사용이라고 경고를 날리기 시작했습니다. 아무래도 6버전의 사용방법으로 바꿔야할 것 같네요.
6버전 + next 9 이상의 getStaticProps, getServerSideProps
5버전과 많이 달라졌습니다.
주의할 점은 Provider로 감싸지 않는다는 점, next-redux-wrapper가 알아서 store를 실은 후 자동으로 감싸준다는 점입니다.
또, 이상하게 redux devtools 가 오류가 나서 패키지를 설치해서 연결했습니다. 앞으로도 패키지를 설치하는 방향으로 데브 툴즈를 쓸 것 같습니다.
(https://www.npmjs.com/package/redux-devtools-extension)
import { createStore, applyMiddleware, compose } from "redux";
import { createWrapper } from "next-redux-wrapper";
import { createLogger } from "redux-logger";
import { composeWithDevTools } from "redux-devtools-extension";
import rootReducer from "./index";
const configureStore = () => {
const logger = createLogger();
const enhancer = compose(composeWithDevTools(applyMiddleware(logger)));
const store = createStore(rootReducer, enhancer);
return store;
};
const wrapper = createWrapper(configureStore, { debug: true });
export default wrapper;
./_app.js
import wrapper from "../reducers/configureStore";
function MyApp({ Component, pageProps }) {
return (
<>
<AppLayout>
<Component {...pageProps} />
</AppLayout>
</>
);
}
// 감싸기
export default wrapper.withRedux(MyApp);
각 세부 페이지의 getInitialProps, getServerSideProps와의 결합
(wrapper로 감싸줘야 context에 store가 생기고, 이를 이용해 dispatch를 날릴 수 있습니다.)
export const getServerSideProps = wrapper.getServerSideProps(
async (context) => {
let { page } = context.query;
if (page === undefined) page = 1;
context.store.dispatch({ type: POST_REQUEST });
return {
props: {}, // will be passed to the page component as props
};
}
);
만약 Redux-Saga를 사용하실 예정이라면 next-redux-saga를 설치하고 전체를 wrapping해야 합니다.
https://github.com/bmealhouse/next-redux-saga
'React, Next, Redux > ▲ Next.js' 카테고리의 다른 글
Next.js 프로젝트의 구조와 Data Fetching 플로우 (0) | 2020.08.15 |
---|---|
getInitialProps 사용법 (0) | 2020.08.15 |
express로 Next 커스텀 프론트 서버 구축하기 (0) | 2020.06.25 |
next/link, head, router, dynamic, error, image (0) | 2020.06.24 |
pages/_app.js 을 통한 global CSS와 기본 Layout 설정 (0) | 2020.06.24 |