redux는 상태관리에 주로 사용된다. 사용하다 보면 치명적인 단점이 하나 있는데 바로 페이지를 새로고침 할 경우 state가 날아가버린다는 것이다.
이것에 대한 대응 방안으로 localStorage또는 sessionStorage에 저장하는 방법을 많이 사용하는데 이과정을 편리하게 하기 위해 redux-persist가 사용된다.
이포스팅에는 redux가 이미 세팅되어 있다고 가정한다.
npm install redux-persist
import storage from 'redux-persist/lib/storage
import storageSession from 'redux-persist/lib/storage/session
import { configureStore } from '@reduxjs/toolkit';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import { createSlice } from '@reduxjs/toolkit';
// counterSlice라는 Reducer생성
const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0,
},
reducers: {
increment: (state) => {
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
},
});
//persist설정 하기
const persistConfig = {
key: 'counter',
storage, //localStorage를 불러왔다.
};
//리듀서를 세팅한다.
const persistedReducer = persistReducer(persistConfig, counterSlice.reducer);
//persist 설정을 마친 reducer를 configureStore에 등록한다. 이러면 여러개 등록할 수 있음
const store = configureStore({
reducer: persistedReducer,
});
//지속적으로 localStorage와 store를 일치시킨다.
const persistor = persistStore(store);
//전역으로 설정하기 위해 export한다.
export { store, persistor };
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { store, persistor } from './store';
function App() {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
{/* 애플리케이션 코드 */}
</PersistGate>
</Provider>
);
}
React에서 전역으로 변수를 안전하게 사용할 수 있다.
next.js에서 사용하려면 wrapper 를 만들어 사용할 필요가 있다.
// /store/index.js
import { createStore } from 'redux';
import { persistReducer, persistStore } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import { createWrapper } from 'next-redux-wrapper';
import rootReducer from './reducers';
const persistConfig = {
key: 'root',
storage,
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = createStore(persistedReducer);
const makeStore = () => store;
const wrapper = createWrapper(makeStore, { debug: true });
export { store, persistStore, wrapper };
wrapper라는 변수를 createWrapper를 통해 만들었다.
적용하기
// pages/index.js
import { useSelector } from 'react-redux';
import { wrapper } from '../store';
function Home() {
const count = useSelector((state) => state.count);
return (
<div>
<h1>Count: {count}</h1>
</div>
);
}
export const getStaticProps = wrapper.getStaticProps(async ({ store }) => {
store.dispatch({ type: 'INCREMENT' });
});
export default Home;
getStaticProps를 감싸서 사용하는 모습을 볼 수 있다.