redux-persist 사용하기

이은지·2023년 12월 31일
0

문제 상황

테이브 연합 프로젝트를 진행하면서, 사용자 로그인 시 로그인 api를 통해 userId를 받고, userId를 통해 조회한 사용자 정보를 리덕스로 관리하고자 하였음. 그러나, 사용자가 새로고침 하면 스토어에 저장된 state가 리셋되어, 사용자 정보가 초기화 되어버리는 문제 발생

해결 방법

Redux persist를 통해 사용자가 새로고침 해도 리덕스 스토어에 사용자 정보를 유지

Redux-persist의 원리와 사용하는 이유

  • 페이지를 새로고침할 경우, 리덕스의 store의 state가 리셋 되는 문제를 해결하기 위해 사용
  • 새로고침해도 state 값이 사라지지 않도록, reducer state를 localStorage 또는 session에 저장
    • localStorage에 저장할 경우

      import storage from 'redux-persist/lib/storage
    • session Storage에 저장할 경우

      import storageSession from 'redux-persist/lib/storage/session

Redux-persist 사용법

1. redux-persist 설치

npm install redux-persist

2. reducer에 persist store 정의

  • persisConfig = { } : 새로운 persist의 선언
  • persistReducer(persisConfig, reducer) : persisConfig가 추가된 reducer 반환
import { combineReducers } from 'redux';
import Schedule from './schedule';
import Memo from './memo';
import Plan from './plan';
import User from './user';
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage'; // defaults to localStorage for web

const rootReducer = combineReducers({
  Schedule, Memo, Plan, User
});

const persistConfig = {
	//reducer의 어느 지점에서부터 데이터를 저장할 것인지 지정
  key: 'root', 
	//localStorage에 저장함
  storage, 
	// User 리듀서만 localstorage에 저장하게 설정
  whitelist: ['User'] 

	// blacklist -> 그것만 제외
};

export const persistedReducer = persistReducer(persistConfig, rootReducer);

3. persist store 사용

  • persistStore() : 새로 고침, 종료해도 지속될 store를 생성 (로컬 스토리지에 저장하고 관리할 store)
  • PersistGate: persist store가 redux에 저장될 때까지 앱 UI 렌더링이 지연됩니다.
    • loading : store를 불러오는 과정(로딩) 중에 보여줄 컴포넌트
    • persistor : 로컬스토리지에 저장할 스토어
/* eslint-disable */
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { QueryClient, QueryClientProvider } from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools';
import { ThemeProvider } from 'styled-components';
import { colorTheme } from './styles/theme';
import { GlobalStyle } from './styles/global-style';
import { composeWithDevTools } from 'redux-devtools-extension';
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import rootReducer, { persistedReducer } from './services';
import { PersistGate } from 'redux-persist/integration/react';
import { persistStore } from "redux-persist";

const root = ReactDOM.createRoot(document.getElementById('root'));
const queryClient = new QueryClient();
const store = createStore(persistedReducer, composeWithDevTools());
const persistor = persistStore(store);
root.render(
  <Provider store={store}>
    <QueryClientProvider client={queryClient}>
    <PersistGate loading={null} persistor={persistor}>
      <ReactQueryDevtools initialIsOpen={true} />
      <GlobalStyle />
      <ThemeProvider theme={colorTheme}>
        <App />
      </ThemeProvider>
      </PersistGate>
    </QueryClientProvider>
  </Provider>,
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
profile
소통하는 개발자가 꿈입니다!

0개의 댓글