이번에 과제를 하면서 redux 환경에서 local storage를 적용해야 하는 문제가 있어서 알아 보던 중에 redux prsist라는 라이브러리가 있다는 것을 알게 되었다! 생각보다 적용하기 쉬워서 바로 프로젝트에 적용해볼 수 있었다.
추가로 redux thunk라고 데이터를 비동기로 처리할 수 있게 해주는 라이브러리도 있어서 함께 공부해보았다.
redux thunk
redux는 기본적으로 동기적인 코드만 처리할 수 있다.
그런데 API 요청은 시간이 걸리니까 비동기 작업으로 처리해야 한다.
이 때 redux-thunk를 사용하여 비동기 작업을 처리할 수 있다.
redux-thunk는 비동기 작업을 처리할 수 있게 도와주는 미들웨어이다.
[기존 방식]
const App = () => {
const dispatch = useDispatch();
return (
<div>
<button
onClick={() => {
dispatch({ type: "PLUS_ONE" });
}}
> + 1
</button>
</div>
);
};
기존에는 이런식으로 dispatch에 액션을 넣는 식으로 작성하였다.
- PULS_ONE이라는 액션이 dispatch되고 리듀서가 이 액션을 받아서 +1 해주는 코드
[thunk 사용]
const plusOneAsync = () => {
return (dispatch) => {
setTimeout(() => {
dispatch({ type: 'PLUS_ONE' }); // 3초 뒤에 액션 실행!
}, 3000);
};
};
thunk 액션 함수를 따로 작성해준다. pulsOneAsync → 3초 뒤에 액션이 실행되는 비동기 함수
<button onClick={() => dispatch(plusOneAsync())}>
+1 (3초 뒤에)
</button>
기존에는 dispatch() 안에 액션값을 넣어주었다면 thunk를 사용할 때는 thunk 함수를 넣어주면 된다.
const store = createStore(rootReducer, applyMiddleware(thunk));
store.js에서 store에 thunk를 미들웨어로 넣어줘야 한다.
applyMiddleware(thunk)를 넣어준다!
api를 받아온다고 생각하면 이런식으로 처리할 수 있다.
이 비동기 작업을 컴포넌트에서 직접 수행할 수도 있지만 비동기 작업과 redux 상태 코드가 한 곳에 모여있지 않기 때문에 redux-thunk를 사용한다고 한다.
이렇게 되면 컴포넌트에서는 useDispatch로 thunk 함수만 호출하면 되기 때문에 컴포넌트 코드가 깔끔해진다.
export const fetchUser = () => {
return async (dispatch) => {
dispatch({ type: 'FETCH_USER_START' }); // 로딩 시작 표시
try {
const res = await fetch('/api/user');
const data = await res.json();
dispatch({ type: 'FETCH_USER_SUCCESS', payload: data }); // 성공 시
} catch (error) {
dispatch({ type: 'FETCH_USER_ERROR', error }); // 실패 시
}
};
};
Redux Persist
redux는 새로고침을 하지 않는 이상 상태가 유지되는데 새로고침을 하면 상태가 날아간다는 문제점이 있다.
redux-persist를 사용하면 리덕스의 상태를 localStorage에 저장할 수 있다.
이 라이브러리를 사용하면 새로고침을 해도 상태가 유지될 수 있다.
생각보다 적용 방법도 간단하다.
[persist 설정]
import { persistStore, persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import { createStore } from 'redux';
import rootReducer from './reducers';
const persistConfig = {
key: 'root',
storage,
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
export const store = createStore(persistedReducer);
export const persistor = persistStore(store);
store를 persist로 감싸서 새 리듀서로 store를 생성한다.
- key: 'root' : 저장할 때 루트 키 이름
- storage : 어디에 저장할건지
[app 감싸기]
ReactDOM.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>,
document.getElementById('root')
);
<PersistGate> 로 감싸주기만 하면 적용 끝이다.
'Develop > FE' 카테고리의 다른 글
| [React] Axios Instance & Interceptors (0) | 2025.06.05 |
|---|---|
| React + PWA + Vite 프로젝트 시작하기 (feat. tailwind) (0) | 2025.04.19 |
| [React] fragments, forward props, 여러 JSX 슬롯 활용법 (1) | 2024.11.29 |
| [React] Context (1) | 2024.11.12 |
| [React] Lists and Keys & Forms & Lifting State Up (1) | 2024.10.08 |