개발 환경은 노드JS, 코드 실행은 브라우저, 상태 유지는 로컬 스토리지
Redux-persist는 리덕스 스토어의 상태를 지속적으로 유지하기 위한 라이브러리입니다
설치
npx create-react-app .
npm install react-router-dom redux redux-thunk react-redux axios styled-components
npm install -D redux-devtools-extension
npm install redux-persist
[Store.jsx]
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { rootReducer } from "./rootReducer";
import { composeWithDevTools } from "redux-devtools-extension";
import { persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage"
const persistConfig = {
key: 'root',
// 세션 or 로컬 스토리지. 기본은 로컬 스토리지입니다
storage: storage,
}
// 첫번째 인자는 config 객체, 두번째 인자는 reducer
const persistedReducer = persistReducer(persistConfig, rootReducer)
const enhancer =
process.env.NODE_ENV === "production"
? applyMiddleware(thunk)
: composeWithDevTools(applyMiddleware(thunk));
export const store = createStore(persistedReducer, enhancer);
export const persistor = persistStore(store)
애플리케이션 탭의 로컬 스토리지에 root라는 키값으로 전역상태 객체가 저장된 것을 확인할 수 있습니다
[user/reducer.jsx]
import { USER_LOGIN, USER_LOGOUT, USER_REQUEST_ERROR } from "./types";
const initialState = {
isLoading: true,
isError: null,
isLogin: false,
user: {
userid: "",
username: "",
},
};
export const user = (state = initialState, action) => {
switch (action.type) {
case USER_LOGIN:
return {
...state,
isLoading: false,
isLogin: action.payload.isLogin,
user: action.payload.user,
};
case USER_LOGOUT:
return {
...state,
isLoading: false,
isLogin: false,
user: { userid: "", username: "" },
};
case USER_REQUEST_ERROR:
return { ...state, isLoading: false, isError: action.payload.message };
default:
return state;
}
};
[Login.jsx]
import { useDispatch, useSelector } from "react-redux";
import { userLogin } from "../store/user";
import { useNavigate } from "react-router-dom";
export const Login = () => {
const dispatch = useDispatch();
const { isLoading, isError, isLogin, user } = useSelector(
(state) => state.user
);
const navigate = useNavigate();
const handleLogin = () => {
dispatch(userLogin(true, { userid: "web7722", username: "Kim" }));
navigate("/");
};
return (
<>
<button onClick={handleLogin}>Login</button>
</>
);
};
모든 전역 상태를 로컬 스토리지에 담아서 관리할 필요는 없습니다 (리소스 낭비)
유저에 관한 상태만 저장하기 위해 Store를 아래와 같이 수정합니다
[Store.jsx]
const persistConfig = {
key: 'root',
// 세션 or 로컬 스토리지
storage: storage,
whitelist:['user']
}
카테고리에 관한 상태가 없어진 것을 확인!