Fittering 개발 기록 - 리덕스 새로고침 상태 초기화 이슈

thumbzzero·2023년 10월 3일
1

기존 구현


마이페이지 조회 API를 통해 불러온 회원 정보는

  1. 마이페이지의 "${username}님 안녕하세요" 문구
  2. 마이페이지에서 회원정보 수정 버튼을 눌렀을 때 나오는 회원 정보 수정 페이지의 폼에서 inputplaceholder

에서 사용된다.

회원 정보 수정 페이지는 마이페이지에서 들어가므로,
마이페이지 조회 API를 마이페이지와 회원 정보 수정 페이지 모두에서 호출하기보다는 마이페이지에서만 호출한 뒤 해당 정보를 회원 정보 수정 페이지에서도 사용할 수 있도록 회원 정보를 전역 상태로 두었다.

따라서 마이페이지에서는

useEffect(() => {
  dispatch(fetchMyPage());
}, [dispatch]);

와 같이 마이페이지 조회 API를 호출한 뒤 전역 상태를 업데이트하고,

회원 정보 수정 페이지에서는

const myPage: MyPage = useAppSelector((state) => state.myPage);

별도의 API 호출 없이 store에 저장된 유저 정보를 가져와서 회원 정보 수정폼의 inputplaceholder로 띄우도록 하였다.

문제


마이페이지에서 회원정보 수정 버튼을 눌렀을 때에는 placeholder에 정상적으로 표시되나, 회원 정보 수정 페이지에서 새로고침을 할 경우 API 응답 결과로 업데이트되기 전의 초기 상태로 돌아가 placeholder에 유저 정보가 올바르게 표시되지 않는 문제가 있었다.

원인과 해결


리덕스는 새로고침하거나 창을 닫으면 store에 저장된 state가 초기화된다고 한다.

따라서 redux-persist를 통해서 상태를 유지해야 한다.

타입스크립트 버전 설치 : yarn add redux-persist @types/redux-persist

수정 후 코드

rootReducer.ts

import { combineReducers } from '@reduxjs/toolkit';
import myPageReducer from './myPageSlice';
import storage from 'redux-persist/lib/storage';
import { persistReducer } from 'redux-persist';

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

const rootReducer = combineReducers({
  myPage: myPageReducer,
});

export default persistReducer(persistConfig, rootReducer);

store.ts

import { configureStore } from '@reduxjs/toolkit';
import persistStore from 'redux-persist/lib/persistStore';
import rootReducer from './rootReducer';

export const store = configureStore({
  reducer: rootReducer
});

export default store;

export const persistor = persistStore(store);

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

app/user/layout.tsx

'use client';

import store, { persistor } from '@/store/store';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';

export default function MyPageLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <>
      <Provider store={store}>
        <PersistGate persistor={persistor}>{children}</PersistGate>
      </Provider>
    </>
  );
}

참고

공식 문서
참고 블로그

0개의 댓글