[typescript] 타입스크립트를 사용한 Redux 상태 관리의 프로젝트 구조

Redux는 JavaScript 앱을 위한 상태 관리 라이브러리로, 앱의 상태를 예측 가능하도록 만들어줍니다. 이번에는 Redux와 타입스크립트를 이용하여 프로젝트를 구성하는 방법에 대해 알아보겠습니다. 이 구조는 큰 규모의 프로젝트에도 적용할 수 있으며, 타입 안정성과 유지 보수성을 높일 수 있습니다.

1. 폴더 구조

일반적으로 Redux와 타입스크립트를 사용하는 프로젝트의 구조는 다음과 같습니다.

project/
│
├── src/
│   ├── actions/
│   ├── reducers/
│   ├── store/
│   └── types/
│
└── tsconfig.json

2. 액션과 액션 생성자

// types/actions.ts
export const ADD_TODO = 'ADD_TODO';
export const REMOVE_TODO = 'REMOVE_TODO';

// actions/todoActions.ts
import { ADD_TODO, REMOVE_TODO } from '../types/actions';

export interface Todo {
  id: number;
  text: string;
}

export interface AddTodoAction {
  type: typeof ADD_TODO;
  payload: Todo;
}

export interface RemoveTodoAction {
  type: typeof REMOVE_TODO;
  payload: number;
}

export type TodoActionTypes = AddTodoAction | RemoveTodoAction;

export function addTodo(newTodo: Todo): AddTodoAction {
  return {
    type: ADD_TODO,
    payload: newTodo
  };
}

export function removeTodo(id: number): RemoveTodoAction {
  return {
    type: REMOVE_TODO,
    payload: id
  };
}

3. 리듀서

// reducers/todoReducer.ts
import { Todo, TodoActionTypes, ADD_TODO, REMOVE_TODO } from '../types/actions';

interface TodoState {
  todos: Todo[];
}

const initialState: TodoState = {
  todos: []
};

const todoReducer = (state = initialState, action: TodoActionTypes): TodoState => {
  switch (action.type) {
    case ADD_TODO:
      return {
        ...state,
        todos: [...state.todos, action.payload]
      };
    case REMOVE_TODO:
      return {
        ...state,
        todos: state.todos.filter(todo => todo.id !== action.payload)
      };
    default:
      return state;
  }
};

export default todoReducer;

4. 스토어

// store/configureStore.ts
import { createStore } from 'redux';
import todoReducer from '../reducers/todoReducer';
import { TodoActionTypes } from '../types/actions';

const store = createStore(todoReducer);

export default store;

5. 타입 정의

// types/actions.ts
export const ADD_TODO = 'ADD_TODO';
export const REMOVE_TODO = 'REMOVE_TODO';

// actions/todoActions.ts
// ...

// reducers/todoReducer.ts
// ...

// store/configureStore.ts
// ...

// types/index.ts
export * from './actions';

6. 컨테이너에서 사용하기

// components/TodoList.tsx
import React from 'react';
import { connect } from 'react-redux';
import { AppState } from '../types';

interface TodoListProps {
  todos: Todo[];
}

const TodoList: React.FC<TodoListProps> = ({ todos }) => {
  return (
    <ul>
      {todos.map(todo => (
        <li key={todo.id}>{todo.text}</li>
      ))}
    </ul>
  );
};

const mapStateToProps = (state: AppState) => ({
  todos: state.todos
});

export default connect(mapStateToProps)(TodoList);

이러한 구조를 사용하여 애플리케이션의 Redux 상태 관리를 효율적이고 유지보수가 쉽도록 구현할 수 있습니다. 타입스크립트를 사용하여 액션과 리듀서를 정의하고 사용하면 코드의 안정성과 가독성을 향상시킬 수 있습니다.

제가 참고한 자료는 다음과 같습니다:

부담 없이 언제든지 질문해주세요!