본문 바로가기

개발 공부/React

Redux login 예시

 

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;