프로세스
Redux에 로그인 정보를 담아서 전역적으로 사용할 수 있도록 합니다.
상태를 관리하는 Store가 따로 존재합니다.
코드 작성법
폴더 구조
store
- LoginDataSlice.js
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
token: '',
name: '',
isValidToken: false
};
const LoginDataSlice = createSlice({
name: 'loginData',
initialState,
reducers: {
login(state, action) {
return {...initialState, ...action.payload, isValidToken: true};
},
logout(state) {
state.token = '';
state.name = '';
state.isValidToken = false;
},
tokenExpired(state) {
state.isValidToken = false;
}
}
});
export const {login, logout, tokenExpired} = LoginDataSlice.actions;
export default LoginDataSlice.reducer;
- index.js
import { combineReducers } from 'redux';
import { configureStore } from "@reduxjs/toolkit";
import loginDataSlice from "./slices/LoginDataSlice";
const reducers = combineReducers({
loginData: loginDataSlice,
});
const store = configureStore({
reducer: reducers,
// state에 function을 사용하기 위해 선언
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: false
})
});
export default store;
App.js
import PrivateRoutes from "./routes/private";
import PublicRoutes from "./routes/public";
import { useSelector } from "react-redux";
function App() {
const {isValidToken} = useSelector((state) => state.loginData);
return (
<>
{
isValidToken ?
<PrivateRoutes />
:
<PublicRoutes />
}
</>
);
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import store from "./store";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<BrowserRouter>
<App/>
</BrowserRouter>
</Provider>
);
reportWebVitals();
localStorage를 사용하는 경우
redux-persist 설치
yarn add redux-persist
or
npm install redux-persist
store
- slices
- LoginDataSlice.js
import { createSlice } from "@reduxjs/toolkit";
const initialState = {
token: '',
name: '',
isValidToken: false
};
const LoginDataSlice = createSlice({
name: 'loginData',
initialState,
reducers: {
login(state, action) {
return {...initialState, ...action.payload, isValidToken: true};
},
logout(state) {
state.token = '';
state.name = '';
state.isValidToken = false;
},
tokenExpired(state) {
state.isValidToken = false;
}
}
});
export const {login, logout, tokenExpired} = LoginDataSlice.actions;
export default LoginDataSlice.reducer;
- index.js
import { combineReducers } from 'redux';
import { configureStore } from "@reduxjs/toolkit";
import loginDataSlice from "./slices/LoginDataSlice";
import storage from 'redux-persist/lib/storage';
import LoginDataSlice from "./slices/LoginDataSlice";
import { persistReducer, persistStore } from "redux-persist";
// persistReducer를 전체 reducer가 들어있는 reducers를 기준으로 사용하면 whitelist, blacklist는 reducer(slice) name이다.
const rootPersistConfig = {
key: 'root',
storage,
blacklist: ["loginData"], // reducer name
}
// persistReducer를 특정 reducer에 사용하면 whitelist, blacklist는 reducer안에 state name 이다.
const persistConfig = {
key: 'login',
storage,
whitelist: ["token", "name"], // state name
};
const reducers = combineReducers({
loginData: persistReducer(persistConfig, loginDataSlice), // 특정 state를 지정한 per
});
const store = configureStore({
reducer: persistReducer(rootPersistConfig, reducers), // 특정 reducer를 지정한 persist
// state에 function을 사용하기 위해 선언
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: false
})
});
export const persist = persistStore(store);
export default store;
App.js
import PrivateRoutes from "./routes/private";
import PublicRoutes from "./routes/public";
import { useSelector } from "react-redux";
function App() {
const {isValidToken} = useSelector((state) => state.loginData);
return (
<>
{
isValidToken ?
<PrivateRoutes />
:
<PublicRoutes />
}
</>
);
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import reportWebVitals from './reportWebVitals';
import {BrowserRouter} from "react-router-dom";
import {Provider} from "react-redux";
import store from "./store";
import {persist} from "./store";
import {PersistGate} from "redux-persist/integration/react";
import {persistStore} from "redux-persist";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<PersistGate loding={null} persistor={persist}>
<BrowserRouter>
<App/>
</BrowserRouter>
</PersistGate>
</Provider>
);
reportWebVitals()
장단점
- 장점
- 랜더링 여부를 선택할 수 있다. (부분 랜더링 가능)
- 애플리케이션이 커지고 복잡해져도 문제없다.
- 관리하는 데이터가 복잡해도 문제없다.
- saga, thunk 같은 미들웨어를 추가적으로 사용할 수 있다.
- 비동기적인 처리나 사이드 이펙트를 관리하기에 좋다.
- 단점
- dependency가 필요하다.
- 초반 세팅에 시간이 걸린다.
- 코드가 많이 분산되어서 찾기가 불편할 수 있다.
'JS > React' 카테고리의 다른 글
React - 로그인 여부에 따른 Router 관리(Router 나누기) (0) | 2024.03.09 |
---|---|
React - 로그인 정보 관리(React Context 사용) (0) | 2024.03.09 |
React - Atomic Design 이란? (0) | 2024.03.09 |
React - setInterval & setTimeout (0) | 2024.03.09 |
React - ckEditor 사용법 (0) | 2024.03.09 |