1. 프로젝트 생성
npx create-react-app redux-auth-demo --template typescript
cd redux-auth-demo
2. Redux ToolKit 설치
npm install @reduxjs/toolkit react-redux
3. 폴더 구조 만들기
src/
├── store/
│ ├── index.ts ← 스토어 설정
│ └── authSlice.ts ← 로그인 상태 Slice
├── features/
│ └── LoginForm.tsx ← 로그인 컴포넌트
├── App.tsx
├── index.tsx ← Provider 연결
4. Redux 스토어 설정
// src/store/index.ts
import { configureStore } from '@reduxjs/toolkit';
import authReducer from './authSlice';
export const store = configureStore({
reducer: {
auth: authReducer,
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
5. 로그인 상태 Slice 만들기
// src/store/authSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
interface AuthState {
isLoggedIn: boolean;
username: string;
}
const initialState: AuthState = {
isLoggedIn: false,
username: '',
};
const authSlice = createSlice({
name: 'auth',
initialState,
reducers: {
login: (state, action: PayloadAction<string>) => {
state.isLoggedIn = true;
state.username = action.payload;
},
logout: (state) => {
state.isLoggedIn = false;
state.username = '';
},
},
});
export const { login, logout } = authSlice.actions;
export default authSlice.reducer;
6. Redux Provider 연결
// src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { store } from './store';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')!).render(
<Provider store={store}>
<App />
</Provider>
);
7. LoginForm.tsx
// src/features/LoginForm.tsx
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { login } from '../store/authSlice';
import { AppDispatch } from '../store';
const LoginForm = () => {
const [usernameInput, setUsernameInput] = useState('');
const dispatch = useDispatch<AppDispatch>();
const handleLogin = () => {
if (usernameInput.trim() !== '') {
dispatch(login(usernameInput));
}
};
return (
<div>
<input
type="text"
placeholder="Username"
value={usernameInput}
onChange={(e) => setUsernameInput(e.target.value)}
/>
<button onClick={handleLogin}>로그인</button>
</div>
);
};
export default LoginForm;
8.로그인 상태 표시 및 로그아웃
// src/App.tsx
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { RootState, AppDispatch } from './store';
import { logout } from './store/authSlice';
import LoginForm from './features/LoginForm';
function App() {
const dispatch = useDispatch<AppDispatch>();
const { isLoggedIn, username } = useSelector((state: RootState) => state.auth);
return (
<div>
{isLoggedIn ? (
<>
<h2>안녕하세요, {username}님!</h2>
<button onClick={() => dispatch(logout())}>로그아웃</button>
</>
) : (
<LoginForm />
)}
</div>
);
}
export default App;