1. Redux와 React-Redux 설치
npm install @reduxjs/toolkit react-redux
- typescript인 경우 추가로 @types/react-redux 설치
npm install @types/react-redux
2. Slice 생성 (userSlice.ts)
2-1. Redux Toolkit을 사용한 상태 관리(slice) 설정
- 로그인 후 id와 token을 저장
1) UserState 인터페이스 정의
interface UserState {
id: string | null;
token: string | null;
}
2) initialState 초기 상태 설정
const initialState: UserState = {
id: null,
token: null
};
3) createSlice를 사용한 상태 관리 설정
const userSlice = createSlice({
name: 'user',
initialState,
reducers: { ... }
});
- createSlice는 리듀서(reducer)와 액션(action)을 한 번에 생성하는 함수
- name: 'user': 이 상태의 이름을 "user"로 설정
- initialState: 초기 상태를 설정
- reducers: 상태를 변경하는 함수(액션 생성)
2-2. 상태 변경을 위한 리듀서 함수 (reducers) 정의
1) setUser : 로그인 정보 저장
setUser: (state, action: PayloadAction<{ id: string; token: string }>) => {
state.id = action.payload.id;
state.token = action.payload.token;
}
2) resetUser : 로그아웃 시 상태 초기화
resetUser: (state) => {
state.id = null;
state.token = null;
}
2-3. 전체 코드
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
interface UserState {
id: string | null;
token: string | null;
}
const initialState: UserState = {
id: null,
token: null
};
const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
setUser: (state, action: PayloadAction<{ id: string; token: string }>) => {
state.id = action.payload.id;
state.token = action.payload.token;
},
resetUser: (state) => {
state.id = null;
state.token = null;
}
}
});
export const { setUser, resetUser } = userSlice.actions;
export default userSlice.reducer;
3. Store 설정 (store.ts)
- userSlice를 store에 등록
3-1. Redux 스토어 생성
const store = configureStore({
reducer: {
user: userReducer,
},
});
3-2. RootState 타입 정의
export type RootState = ReturnType<typeof store.getState>;
- store.getState()는 현재 Redux의 전체 상태를 반환하는 함수.
- ReturnType<typeof store.getState> → store.getState()의 반환 타입을 자동으로 가져와 RootState 타입으로 정의.
- 이후 Redux 상태를 사용할 때 TypeScript가 타입을 추론할 수 있도록 함.
- 사용 예시
const user = useSelector((state: RootState) => state.user);
3-3. AppDispatch 타입 정의
export type AppDispatch = typeof store.dispatch;
- store.dispatch의 타입을 가져와 AppDispatch로 정의.
- Redux에서 dispatch()를 사용할 때, 올바른 액션을 전달하도록 TypeScript가 검사할 수 있도록 함.
3-4. 전체코드
import { configureStore } from '@reduxjs/toolkit';
import userReducer from './userSlice';
const store = configureStore({
reducer: {
user: userReducer,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
export default store;
4. main.tsx에 Provider 추가
- 기존 코드
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
)
- 수정된 코드
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import { Provider } from 'react-redux'
import store from '@store/store'
createRoot(document.getElementById('root')!).render(
<StrictMode>
<Provider store={store}>
<App />
</Provider>
</StrictMode>,
)
5. 컴포넌트에서 활용 (예시)
import { useDispatch, useSelector } from "react-redux";
import { setUser, resetUser } from "./userSlice";
import { RootState } from "./store"; // Redux store 타입
const Login = () => {
const dispatch = useDispatch();
const user = useSelector((state: RootState) => state.user);
const handleLogin = () => {
dispatch(setUser({ id: "user123", token: "abcd1234" }));
};
const handleLogout = () => {
dispatch(resetUser());
};
return (
<div>
<h2>로그인 상태: {user.id ? `ID: ${user.id}` : "로그아웃됨"}</h2>
<button onClick={handleLogin}>로그인</button>
<button onClick={handleLogout}>로그아웃</button>
</div>
);
};
export default Login;
* Redux store 는 새로고침 시 저장된 데이터들이 사라진다.
새로고침 시에도 사라지지 않고 저장되길 원한다면 로컬 스토리지를 사용하거나 Redux Persist 사용하여 구현하면 된다.
'프로그래밍 언어 > React' 카테고리의 다른 글
[React] antd ant-design 504 (Outdated Optimize Dep) 오류 (0) | 2025.03.11 |
---|---|
[React] lazy 코드 스플리팅 (0) | 2025.03.10 |
[React] React + Vite + Ant Design 설정 방법 (0) | 2025.03.06 |
[React] 컴포넌트 간 데이터 전달(부모 <-> 자식) (1) | 2025.03.02 |
[React] react + vite + typescript 절대경로 설정방법 (0) | 2025.03.01 |