본문 바로가기
배움 기록/React

[React] Redux-persist 사용법(Redux toolkit ver.) (+ Next.js, TypeScript)

by dygreen 2023. 5. 30.

이번에 회사 이벤트 페이지들을 Vue에서 React로 바꾸게 되었는데,

Redux toolkit을 사용하여 필요한 정보를 가져와 화면에 표시하였다.

그러나 store는 새로고침하면 값이 날아가기 때문에

새로고침 시 해당 화면이 그려지지 않는 문제가 발생했다.

 

이 문제를 해결하기 위해 Redux-persist를 사용하면 좋을 것 같았다.

 

📌 Redux-persist ?

  • Redux-persist는 store 값을 localStorage나 sessionStorage에 저장하여 새로고침해도 데이터를 유지된다.
  • 새로고침 시 저장공간에 있는 데이터를 Redux에 불러오는 형식으로 이루어진다.

 

📌 Redux-persist 적용하기 (Redux toolkit ver.)

( Redux toolkit 사용 방법 )

[store] : /store/slices.ts
import {combineReducers, configureStore, createSlice} from '@reduxjs/toolkit'
import type {PayloadAction} from '@reduxjs/toolkit'
import storage from 'redux-persist/lib/storage'
import {persistReducer} from 'redux-persist'

const store1 = createSlice({
  name: 'store1',
  initialState,
  reducers: {
    returnStore1(state = initialState) {
      return state
    }
  }
})

const reducers = combineReducers({
  store1: store1.reducer,
})

const persistConfig = {
  key: 'root',
  storage,
  whitelist: ['store1'],
}

export const store = configureStore({
  reducer: persistReducer(persistConfig, reducers),
})

export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch

export const { returnStore1 } = store1.actions
  • combineReducers, persistReducer를 import 한다.
  • combineReducers에 reducer를 넣는다. (⇒ reducers)
  • reducers를 configureStore에 전달한다.
    : combineReducers는 Redux의 API로 여러개의 reducer를 하나의 root reducer로 합쳐준다.
    Redux toolkit을 사용하면 configureStore가 configureStore의 object를 combineReducers utility에 넘겨, 자동으로 root reducer를 생성하기 때문에 combineReducers를 사용할 필요가 없다.
    그러나 Redux persist를 사용할 경우 persistReducer에 (combineReducers를 사용하여) 하나의 reducer를 전달하고, 반환받은 enhanced reducer를 configureStore에 전달해야 하기 때문에 combineReducers를 사용해야 한다.
  • configureStore에 전달할 때는 persistReducer를 사용한다.
    : persistReducer는 reducer를 반환하는 API이다.


    persistReducer(config, reducer)
    • config : key와 storage를 필수로 하며, whitelist, blacklist 등의 값을 지정할 수 있다.
      • storage : localStorage에 저장하고 싶으면 import storage from 'redux-persist/lib/storageU, sessionStorage에 저장하고 싶으면 import storageSession from 'redux-persist/lib/storage/session
      • whitelist : 유지하고 싶은 값을 배열로 전달함
      • blacklist : 유지하고 싶지 않은 값을 배열로 전달함
    • reducer : combineReducers로 부터 반환받은, 즉 하나로 합쳐진 root reducer를 넣어준다.

 

_app.tsx
import type { AppProps } from 'next/app'
import {store} from "@/store/slices"
import {Provider} from "react-redux"
import {PersistGate} from "redux-persist/integration/react"
import {persistStore} from "redux-persist"

export const persistor = persistStore(store)

export default function App({ Component, pageProps }: AppProps) {
  return (
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
          <Component {...pageProps}/>
        </PersistGate>
      </Provider>
  )
}
  • /store/slices.ts의 store, PersistGate, persistStore를 import 한다.

persistStore

: 유지하고 싶은 redux store를 인자로 넣으면 persistor 객체를 반환한다. (*여기서 store는 /store/slices.ts에서 configureStore에 전달한 reducer)

 

PersistGate

: 유지되는 store의 값이 다시 Redux에 저장될 때까지 app의 렌더링을 지연시킨다.

  • loading : 로딩 과정에서 보여줄 컴포넌트
  • persistor : localStorage에 저장할 store (persistStore가 반환한 persistor 객체를 전달하면 됨)

 

 


참고 :
https://choyeon-dev.tistory.com/entry/Redux-persist-%EC%83%88%EB%A1%9C%EA%B3%A0%EC%B9%A8%EC%97%90%EB%8F%84-%EC%9C%A0%EC%A7%80%EB%90%98%EB%8A%94-store-%EB%A7%8C%EB%93%A4%EA%B8%B0-with-Redux-toolkit
https://kyounghwan01.github.io/blog/React/redux/redux-persist/#reducer%E1%84%8B%E1%85%A6-persist-store-%E1%84%8C%E1%85%A5%E1%86%BC%E1%84%8B%E1%85%B4

 

728x90

댓글