Redux+TS 03 | 리덕스 모듈 파일 분리

Kate Jung·2022년 1월 2일
0

middlewares & libraries

목록 보기
13/17
post-thumbnail

📌 todos 리덕스 모듈 여러 파일로 분리

🔹 분리하는 경우 & 이유 & 방식

  • 분리하는 경우

    파일이 너무 길어질 때

    → 아니면 한 파일에 작성

  • 분리 이유

    상황 : 한 파일에 액션 type, 액션 생성 함수, 액션 객체들의 타입, 상태의 타입, 리듀서를 선언

    → 액션의 수 증가 시, 코드가 너무 길어짐

    → 개발 할 때, 뭘 찾을 경우 스크롤을 많이 하게 됨

    → 생산성 저하 가능성

  • 추천 방식

    src/modules/todos 디렉터리 제작 후, 내부에 파일 작성

    modules
      todos
        actions.ts
        index.ts
        reducer.ts
        types.ts
      counter.ts // 파일 길지 않은 경우: 한 파일로 작성

🔹 액션 (src/modules/todos/actions.ts)

◾ 코드

import { deprecated } from "typesafe-actions";
const { createAction, createStandardAction } = deprecated;

// 액션 타입 (리듀서에서 사용 가능하도록 내보냄)
export const ADD_TODO = "todos/ADD_TODO";
export const TOGGLE_TODO = "todos/TOGGLE_TODO";
export const REMOVE_TODO = "todos/REMOVE_TODO";

// 새로운 항목을 추가 할 때 사용 할 고유 ID 값
let nextId = 1;

// 액션 생성 함수
export const addTodo = createAction(
  ADD_TODO,
  (action) => (text: string) =>
    action({
      id: nextId++,
      text,
    })
);
export const toggleTodo = createStandardAction(TOGGLE_TODO)<number>();
export const removeTodo = createStandardAction(REMOVE_TODO)<number>();

◾ 참고

  • 타입도 내보냄

    리듀서에서 사용 가능하도록

🔹 타입 (src/modules/todos/types.ts)

액션객체들의 타입 & state 타입들 선언

◾ 코드

import { ActionType } from "typesafe-actions";
import * as actions from "./actions";

// 액션 객체에 대한 타입
export type TodosAction = ActionType<typeof actions>;

// 한 개의 투두(객체)에 대한 타입
export type Todo = {
  id: number;
  text: string;
  done: boolean;
};

// state 타입 (Todo 객체로 이루어진 배열)
export type TodosState = Todo[];

◾ 참고

import * as actions & ActionType<typeof actions>

  • import * as actions

    한번에 모두 import 해와서 actions 에 담음

  • ActionType<typeof actions>

    액션의 종류가 많아져도 → 한 줄 작성 가능

→ 매우 간편

🔹 리듀서 (src/modules/todos/reducer.ts)

import { createReducer } from "typesafe-actions";
import { TodosAction, TodosState } from "./types";
import { ADD_TODO, REMOVE_TODO, TOGGLE_TODO } from "./actions";

// 초기 상태 선언
const initialState: TodosState = [];

// 리듀서
const reducer = createReducer<TodosState, TodosAction>(initialState, {
  [ADD_TODO]: (state, action) =>
    state.concat({
      ...action.payload, // id, text 를 이 안에 넣기
      done: false,
    }),
  // 비구조화 할당을 활용하여 payload 값의 이름을 바꿀 수 있음
  [TOGGLE_TODO]: (state, { payload: id }) =>
    state.map((todo) =>
      todo.id === id ? { ...todo, done: !todo.done } : todo
    ),
  [REMOVE_TODO]: (state, { payload: id }) =>
    state.filter((todo) => todo.id !== id),
});

export default reducer;

🔹 index파일 (src/modules/todos/index.ts)

◾ 용도

기존 todos.ts 를 불러 쓴 코드들이 (컨테이너 및 루트 리듀서) 수정(import 경로) 없이 동작하도록

◾ 코드

export { default } from './reducer'; // reducer 를 불러와서 default로 내보내겠다는 의미
export * from './actions'; // 모든 액션 생성함수들을 불러와서 같은 이름들로 내보내겠다는 의미
export * from './types'; // 모든 타입들을 불러와서 같은 이름들로 내보내겠다는 의미

📌 TIPS

🔹 import 단축키 (vscode)

  1. import 안되서 빨간 줄 뜨는 곳에 커서를 두고 단축키 `ctrl+.`
  2. 방향키로 맞는 라이브러리 찾은 뒤 Enter  (마우스로 클릭 x)


참고

profile
복습 목적 블로그 입니다.

0개의 댓글