그때 구현할때도 어려웠는데 다시 봐도 어려워.....
우선
Redux의 기본 사용 방식은
createStore로 Store를 생성하고, 리듀서를 통해 상태를 관리하는 방식을 사용한다. 기본 Redux 사용 방식에서는 다중 리듀서를 관리하거나, 상태를 로컬 저장소에 영구적으로 저장하려면 추가적인 설정이 필요함.
🔍 상태 영속화 없음: 기본적인 Redux 설정에서는 상태를 로컬 저장소(localStorage)나 세션 저장소에 영구적으로 저장하지 않으며, 애플리케이션을 새로고침하면 상태가 초기화된다. -> 이거때문에 내가 뒤에서 설명하는 방식을 선택했다.
import { createStore } from 'redux';
import alarmReducer from './alarmReducer';
// Store 생성
const store = createStore(alarmReducer);
// Store에서 현재 상태 가져오기
console.log(store.getState()); // { alarms: [], isLoading: false }
그래서 내가 선택한 방식은 Redux Toolkit 및 redux-persist를 활용한 상태 관리
기존의 기본 Redux에서는 상태를 관리하기 위해서는 createStore를 사용하고 리듀서를 정의하는 방식으로 상태 관리를 해야 했는데, 이 방식은 상태를 브라우저에 영구적으로 저장하지 않아서 페이지를 새로고침하면 모든 상태가 사라지는 문제가 있었다.
특히 알림 기능과 같이 상태가 유지되어야 하는 상황에서는 번거롭고 비효율적이었다.,,,
이러한 이유로 Redux Toolkit과 redux-persist를 결합한 상태 관리 방식을 도입했다. 이를 통해 새로고침하거나 앱이 다시 시작될 때도 상태가 유지될 수 있도록 구성했다.
Redux Toolkit?
기본 Redux 설정을 간단하게 해주는 도구로, 상태 관리의 복잡성을 줄여주며, 추가적인 기능을 쉽게 확장할 수 있다.
redux-persist?
상태를 로컬 저장소에 저장하여 새로 고침이나 애플리케이션 재시작 시에도 상태가 유지되도록 해준다.
store.jsx 전체 코드
import { configureStore } from '@reduxjs/toolkit';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage'; // 로컬 저장소를 사용
import alarmReducer from './reducers/alarmReducer';
import userReducer from './reducers/userReducer';
// persist 설정
const persistConfig = {
key: 'root',
storage,
};
// persistReducer로 감싸기
const persistedAlarmReducer = persistReducer(persistConfig, alarmReducer);
const persistedUserReducer = persistReducer(persistConfig, userReducer);
const store = configureStore({
reducer: {
alarm: persistedAlarmReducer,
user: persistedUserReducer,
},
middleware: (getDefaultMiddleware) => getDefaultMiddleware({
serializableCheck: {
ignoredActions: ['persist/PERSIST', 'persist/REHYDRATE'],
},
}),
});
export const persistor = persistStore(store);
export default store;
⬇️⬇️ store.jsx 코드 설명 ⬇️⬇️
import { configureStore } from '@reduxjs/toolkit';
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage'; // 로컬 저장소를 사용
import alarmReducer from './reducers/alarmReducer';
import userReducer from './reducers/userReducer';
configureStore: store를 간단하게 설정하고 생성할 수 있고 간편하게 여러 미들웨어를 추가하거나, 리듀서를 결합할 수 있다.
persistStore: store가 영속적으로 저장될 수 있도록 도와준다. 앱이 실행될 때 저장된 상태를 불러와서 유지하는 역할을 한다.
persistReducer: 일반적인 Redux 리듀서를 persist 가능하게 만들어 주는 함수입니다. 해당 리듀서는 상태를 로컬 저장소에 저장할 수 있도록 변경된다.
storage: redux-persist에서 제공하는 기본 스토리지 엔진으로, 상태를 브라우저의 localStorage에 저장한다. 이를 통해 상태가 브라우저에 영구적으로 저장되며, 새로고침해도 저장된 상태를 유지할 수 있게 한다.
const persistConfig = {
key: 'root', // 영속적으로 저장할 때 사용할 루트 키입니다. 이 키를 기준으로 로컬 저장소에 저장
storage, // localStorage를 사용하여 상태를 저장
};
const persistedAlarmReducer = persistReducer(persistConfig, alarmReducer);
const persistedUserReducer = persistReducer(persistConfig, userReducer);
persistConfig: redux-persist를 설정하는 객체이다.
persistedAlarmReducer & persistedUserReducer
각각의 리듀서를 persistReducer로 감싸서, 알림 상태와 사용자 상태가 로컬 저장소에 영구적으로 저장될 수 있도록 설정한다.
const store = configureStore({
reducer: {
alarm: persistedAlarmReducer,
user: persistedUserReducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: ['persist/PERSIST', 'persist/REHYDRATE'],
},
}),
});
store: configureStore로 Redux store를 생성한다.
reducer: alarm상태를 관리하는 리듀서들을 설정하고 이를 영구적으로 로컬 저장소에 저장된다.
middleware
getDefaultMiddleware는 기본 미들웨어 설정을 가져온다. 여기서 persist/PERSIST 및 persist/REHYDRATE 액션은 직렬화할 필요가 없으므로 serializableCheck 옵션으로 무시된다. 이는 redux-persist에서 사용하는 특수 액션들이기 때문에 무시해도 괜찮다.
이건 제대로 이해를 못해서 따로 더 찾아서 공부해보려구한당
export const persistor = persistStore(store);
export default store;
persistor: persistStore는 store를 영구적으로 관리하기 위한 객체를 생성한다. 이 persistor 객체는 Redux 상태를 로컬 저장소에 저장하고, 페이지 새로고침 시에도 상태를 복구할 수 있도록 해준다.
store: 설정이 완료된 Redux store를 다른 컴포넌트에서 사용할 수 있도록 내보낸다.
⬇️⬇️ store.jsx 코드 요약 ⬇️⬇️
• store.js에서 configureStore를 사용해 Redux store를 생성하고, persistReducer를 사용해 상태를 로컬 저장소에 영구적으로 저장하도록 설정한다.
• persistConfig: 이 설정을 통해 Redux 상태가 브라우저의 localStorage에 저장된다.
• persistReducer: 각각의 리듀서를 영속 가능한 리듀서로 감싸서, 로컬 저장소에 Redux 상태를 저장할 수 있게 한다.
• persistStore: Redux store가 로컬 저장소와 동기화되도록 관리하는 객체. 이 객체가 PersistGate에서 사용된다.
➡️ 이제 index.js에서 PersistGate 컴포넌트를 사용하여 persistor 객체를 통해 로컬 저장소에 저장된 Redux 상태를 불러와서 사용할 수 있도록 설정한다.
index.js 전체 코드
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import store, {persistor} from './store/store';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>
);
reportWebVitals();
Provider:
Redux의 store를 전체 앱에서 사용할 수 있도록 해준다. 이 컴포넌트를 통해 Redux 상태와 액션을 어디서나 접근할 수 있다.
PersistGate:
로컬 저장소에 저장된 상태를 불러올 때까지 애플리케이션의 UI를 잠시 멈추거나 로딩 상태를 표시할 수 있게 한다.
store: Redux의 상태를 관리
persistor: 저장소에 상태를 영구적으로 저장하고 복구하는 객체
-> 위에서 설명한 store.jsx파일에서 가져와서 사용한다.
이 부분을 좀 더 자세히 설명하자면
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>
<Provider store={store}>
전체 애플리케이션을 Redux store로 감싸서 Redux 상태를 모든 컴포넌트에서 사용할 수 있게 한다.
이 컴포넌트는 Redux의 핵심이며, store를 모든 자식 컴포넌트에 주입합니다.
<PersistGate loading={null} persistor={persistor}>
PersistGate는 애플리케이션이 로컬 저장소에서 Redux 상태를 불러오는 동안 UI를 잠시 멈추거나 로딩 상태를 표시하는 역할을 합니다.
하지만 여기서는 loading={null}로 로딩상태일때 아무것도 표시하지 않도록 함 -> 보통 여기에 로딩상태의 컴포넌트 추가한다.
persistor={persistor} -> persistor 객체를 넘겨주어, 로컬 저장소에서 상태를 복원할 수 있도록 설정합니다.
<App />
실제 애플리케이션의 루트 컴포넌트입니다.
PersistGate로 감싸져 있으므로, Redux 상태가 로컬 저장소에서 복원된 후에 렌더링됩니다.
⬇️⬇️ 전체적인 데이터 흐름 ⬇️⬇️
1. 상태 저장: 앱에서 상태가 변경되면 redux-persist가 로컬 저장소에 자동으로 상태를 저장
2. 앱 실행/새로고침: 사용자가 앱을 새로고침하거나 처음 실행하면 로컬 저장소에 저장된 상태를 복원
3. PersistGate: 앱이 실행될 때, Redux store에서 상태를 불러오는 동안 UI가 로딩되거나 멈추지 않도록 PersistGate로 관리
이렇게 작성해서 새로고침할때도 알림이 없어지는 문제는 해결했는데....
새로고침을 하고나면 서버의 SSE연결이 끊기는 문제가 발생했다...!!
'[ Naver Cloud Camp ]' 카테고리의 다른 글
[🚨 TroubleShooting...?] reducer의 persist 설정 분리 (0) | 2024.09.15 |
---|---|
[ZICZONE 프로젝트] Redux와 SSE를 사용한 알림: 알림 구독 관리 (2) | 2024.09.14 |
[ZICZONE 프로젝트] Redux를 사용한 알림 저장: Redux란? (5) | 2024.09.14 |
[ React ] useState hook (1) | 2024.06.02 |
[ React ] props (0) | 2024.06.02 |