본문 바로가기
프로그래밍 실습/React

리액트 초보의 Redux Toolkit 적용기

by wylee 2023. 2. 23.

리액트 프로젝트에서 가장 까다로웠던 부분이 전역적으로 상태를 관리하는 것이였다.

사용자 정보 같은 전역적으로 필요한 데이터들을 가장 최상위 컴포넌트에서 정의하고 자식 컴포넌트로 내려주는 형태로 개발 했었는데 프로젝트가 커지면서 유지보수가 매우 힘들었던 경험이 있다.

 

 

그래서 이번 프로젝트는 Redux를 적용 해보려고 한다.

Redux Toolkit은 Redux를 더 사용하기 쉽게 만들기 위해 Redux에서 공식 제공하는 개발도구이다.

 

 

리액트도 서툴고 타입스크립트도 서툴지만 아래 튜토리얼을 따라 천천히 적용해 보았다.

https://redux.js.org/tutorials/typescript-quick-start

 

TypeScript Quick Start | Redux

- How to set up and use Redux Toolkit and React-Redux with TypeScript

redux.js.org

 

 

 

먼저 프로젝트의 구조부터 설명하자면 src 폴더 아래에 app, const, reducers 폴더를 만들었다.

app : 리덕스 툴킷에 사용되는 hook.ts, store.ts 파일

const : 전역적으로 필요한 상수를 위한 폴더

reducers : 각 reducer를 저장할 폴더

 

 

 

1. userReducer.ts

User의 인터페이스를 만들어 주었다.

initialState 정보를 사용자 정보를 초기화 할때(예를 들어 로그아웃시) 사용할 것 같아 export 시켜주었다.

리듀서는 유저 정보를 수정하는 setUserReducer만 등록했다.

 

import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import { RootState } from '../app/store'
import UserRole from "../const/UserRole"

export interface User {
    id: string
    role: UserRole
}

export const initialStateUser : User = {
    id: '',
    role: UserRole.unAuth
}

export const userSlice = createSlice({
    name: 'user',
    initialState: initialStateUser,
    reducers: {
        setUserReducer: (state, action: PayloadAction<User>)=>{
            state.id = action.payload.id;
            state.role = action.payload.role;
        }
    }
})

export const { setUserReducer } = userSlice.actions
export const getUserReducer = (state: RootState) => state.user
export default userSlice.reducer

 

유저 권한은 enum으로 정의했는데 타입스크립트는 처음이라 이렇게 하는게 맞는 건가요,,? 

 

const enum UserRole {
    admin = "ADMIN",
    user = "USER",
    unAuth = "UN_AUTH"
}

export default UserRole;

 

 

 

2. store.ts

예제에는 여러가지 리듀서를 등록하지만 난 userReducer만 등록했다. 

 

import { configureStore } from '@reduxjs/toolkit';
import userReducer from '../reducers/userReducer';

const store = configureStore({
    reducer:{
        user: userReducer
    }
})

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch
export default store

 

 

 

3. hook.ts

useAppSelector, useAppDispatch을 등록함으로써 각 컴포넌트에서 useSelector나 useDispatch를 매번 설정하지 않고 애플리케이션 전역에서 사용이 가능하다고 한다.

 

import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'

// Use throughout your app instead of plain `useDispatch` and `useSelector`
type DispatchFunc = () => AppDispatch
export const useAppDispatch: DispatchFunc = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector

 

 

 

4. userReducer 테스트

useAppSelector, useAppDispatch를 이용하여 user에 접근해 보겠다.

setUser : id가 wylee, 권한이 user인 사용자를 userReducer를 통해 전역적으로 셋팅

clearUser : 사용자 정보 초기화

consoleUser : 사용자 정보 콘솔 출력

 

import React from 'react';
import './App.css';
import { useAppSelector, useAppDispatch } from './app/hook';
import UserRole from './const/UserRole';
import { initialStateUser, setUserReducer, User } from './reducers/userReducer';

function App() {
  const user = useAppSelector((state) => state.user);
  const dispatch = useAppDispatch();
  
  const setUser = () => {
    let user:User = {id:'wylee', role:UserRole.user};
    dispatch(setUserReducer(user));
  }

  const clearUser = () => {
    dispatch(setUserReducer(initialStateUser));
  }

  const consoleUser = () => {
    console.log('user : ', user)
  }

  return (
    <div className="App">
      <button onClick={setUser}>
        {'setUser'}
      </button>
      <button onClick={clearUser}>
        {'clearUser'}
      </button>
      <button onClick={consoleUser}>
        {'consoleUser'}
      </button>
    </div>
  );
}

export default App;

 

 

 

 

화면은 아래와 같이 만들었다.

 

 

먼저 사용자 정보를 콘솔로 찍어보겠다.

초기에 셋팅한 initialStateUser 상태로 잘 출력된다.

 

 

그렇다면 이제 user 정보를 바꿔보자

setUser 버튼을 클릭한 후 콘솔로 출력해보니 정상적으로 사용자 정보가 변경된 것을 확인했다.

 

 

마지막으로 사용자 정보를 다시 초기화 해보자

clearUser버튼을 클릭하니 사용자 정보가 초기화 되었다.

 

 

 

 

다음으로는 설정한 userReducer를 바탕으로 사용자 로그인을 구현할 예정이다.

코드에서부터 많이 부족해보이지만 계속 사용하다 보면 타입스크립트도 리덕스도 잘 할수 있겠지~!

 

'프로그래밍 실습 > React' 카테고리의 다른 글

react-router-dom 적용  (0) 2023.03.03
React 프로젝트 생성  (0) 2023.02.03

댓글