들어가기 전에..

  • 새로고침하면 로그인이 풀리는 에러 발생!!🤔🤔
    • 리덕스의 store는 페이지를 새로고침 할 경우 state가 날아가서 생기는 문제 ..
    • redux-persist
      => 새로고침해도 state 값이 사라지지 않도록, localstorage에 reducer를 저장하는 것으로 에러 해결!!

구현 과정

설치

npm i redux-persist @types/redux-persist

Storage 종류 선택하여 rootReducer가 있는 곳에 import

  • 메인프로젝트에서 Local Storage를 사용
import storage from 'redux-persist/lib/storage

persistConfig 작성

const persistConfig = {
  key: "root",
  //스토리지에 저장할 때의 키값을 지정
  storage,
  //저장할 스토리지를 지정
  whitelist: ["userInfo"],
  //스토리지에 저장할 리덕스 모듈을 나열
};

combineReducers 작성

const rootReducer = combineReducers({
  userInfo: userSlice.reducer,
});

persistent reducer 작성

const persistedReducer = persistReducer(persistConfig, rootReducer);

persist reducer를 reducers에 할당하고 middleware에서 extra dispatch functions를 ignore list에 할당

  • extra dispatch functions
    • extra dispatch functions는 Redux의 미들웨어에서 사용되는 용어로, Redux 액션의 디스패치를 가로채거나 조작하여 액션의 처리를 변경하는 함수를 말한다. 일반적으로 로깅, 비동기 작업 처리, 예외 처리 등에 사용된다. Redux 미들웨어는 액션과 스토어 사이에 위치하며, 액션을 처리하기 전에 미들웨어에서 추가적인 작업을 수행할 수 있다.
const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }),
});

PersistGate 작성

  • main.tsx에 작성
  • react-redux가 전체 앱을 감싸는 Provider 컴포넌트를 제공하는 것과 같이, redux-persist에서는 PersistGate를 제공
  • persistStore 함수는 store 객체를 구성하여, 우리가 PersistGate 컴포넌트에 전달할 때 호환되도록 만든다.
//나머지 import는 생략
import store from "./Redux/store/store";
import { PersistGate } from "redux-persist/integration/react";
import { persistStore } from "redux-persist";

let persistor = persistStore(store);

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
   <React.StrictMode>
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <App />
      </PersistGate>
    </Provider>
   </React.StrictMode>,
);

구현한 전체 코드

  • slice와 hook.ts는 생략하고 redux-persist관련한 코드
  • main.tsx
import React from "react";
import { Provider } from "react-redux";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./main.css";
import store from "./Redux/store/store";
import { PersistGate } from "redux-persist/integration/react";
import { persistStore } from "redux-persist";

let persistor = persistStore(store);

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
   <React.StrictMode>
    <Provider store={store}>
      <PersistGate loading={null} persistor={persistor}>
        <App />
      </PersistGate>
    </Provider>
   </React.StrictMode>,
);
  • store.ts
import { combineReducers, configureStore } from "@reduxjs/toolkit";
import { userSlice } from "../slice/userSlice";
import { persistReducer, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from "redux-persist";
import storage from "redux-persist/lib/storage";

const rootReducer = combineReducers({
  userInfo: userSlice.reducer,
});

const persistConfig = {
  key: "root",
  storage,
  whitelist: ["userInfo"],
};

const persistedReducer = persistReducer(persistConfig, rootReducer);

const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }),
});

export default store;

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
profile
함께 일하는 프론트엔드 개발자 이성은입니다🐥

0개의 댓글