ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • typesafe-actions를 이용해 모듈 리팩토링 해보기
    개발/React 2022. 7. 14. 22:19

    이건 결과물로 비교해보는 게 좋을 것 같습니다.

     

    리팩토링 전

    const ADD_TODO = 'todos/ADD_TODO' as const;
    const TOGGLE_TODO = 'todos/TOGGLE_TODO' as const;
    const REMOVE_TODO = 'todos/REMOVE_TODO' as const;
    
    let nextId = 1;
    export const addTodo = (text: string) => ({
      type: ADD_TODO,
      payload: {
        id: nextId++,
        text,
      },
    });
    
    export const toggleTodo = (id: number) => ({
      type: TOGGLE_TODO,
      payload: id,
    });
    
    export const removeTodo = (id: number) => ({
      type: REMOVE_TODO,
      payload: id,
    });
    
    type TodosAction =
      | ReturnType<typeof addTodo>
      | ReturnType<typeof toggleTodo>
      | ReturnType<typeof removeTodo>;
    
    export type Todo = {
      id: number;
      text: string;
      done: boolean;
    };
    
    type TodosState = Todo[];
    
    const initialState: TodosState = [];
    
    export default function todos(
      state: TodosState = initialState,
      action: TodosAction
    ): TodosState {
      switch (action.type) {
        case ADD_TODO:
          return state.concat({
            id: action.payload.id,
            text: action.payload.text,
            done: false,
          });
        case TOGGLE_TODO:
          return state.map((todo) =>
            todo.id === action.payload ? { ...todo, done: !todo.done } : todo
          );
        case REMOVE_TODO:
          return state.filter((state) => state.id !== action.payload);
        default:
          return state;
      }
    }

     

    리팩토링 후

    import { ActionType, createAction, createReducer } from 'typesafe-actions';
    
    const ADD_TODO = 'todos/ADD_TODO' as const;
    const TOGGLE_TODO = 'todos/TOGGLE_TODO';
    const REMOVE_TODO = 'todos/REMOVE_TODO';
    
    let nextId = 1;
    export const addTodo = createAction(ADD_TODO, (text: string) => ({
      id: nextId++,
      text,
    }))();
    
    export const toggleTodo = createAction(TOGGLE_TODO)<number>();
    export const removeTodo = createAction(REMOVE_TODO)<number>();
    
    const actions = { addTodo, toggleTodo, removeTodo };
    type TodosAction = ActionType<typeof actions>;
    
    export type Todo = {
      id: number;
      text: string;
      done: boolean;
    };
    
    type TodosState = Todo[];
    
    const initialState: TodosState = [];
    
    const todos = createReducer<TodosState, TodosAction>(initialState)
      .handleAction(addTodo, (state, action) =>
        state.concat({
          ...action.payload,
          done: false,
        })
      )
      .handleAction(toggleTodo, (state, action) =>
        state.map((todo) =>
          todo.id === action.payload ? { ...todo, done: !todo.done } : todo
        )
      )
      .handleAction(removeTodo, (state, action) =>
        state.filter((todo) => todo.id !== action.payload)
      );
    
    export default todos;

     

    해보면서 느낀 것이 있는데요.

    프론트엔드에서 리액트와 같은 라이브러리, Next.js와 같은 프레임워크가 등장하면서

    백엔드만큼은 아니지만 이전보다 나은 표준 개발 방법이란 게 생겼는데요.

    그 과정에서 jQuery 같은 라이브러리를 사용하지 않는 순수 자바스크립트를 이르는 말로

    바닐라 자바스크립트로 개발하는 트렌드가 시작됐었습니다.

     

    프레임워크를 쓰는 이상 굳이 라이브러리를 쓰지 말고 눈에 보이는 코드 줄 수가 늘어난다고 해도

    성능을 고려했을 때 바닐라 자바스크립트를 써주는 게 좋다는 것이었는데요.

     npm으로 수많은 라이브러리가 관리되고 접근성이 워낙 좋기 때문에

    생산성이라는 이름 아래 많은 라이브러리가 사용됩니다.

    하지만 라이브러리를 사용할수록 바닐라 자바스크립트에서 멀어지는 것 같습니다.

     

    라이브러리가 메이저 업데이트가 되면서 기존에 사용하던 함수를 사용 못하게 되는 일이 생길 수 있습니다.

    위 라이브러리도 v4에서는 createStandardAction을 사용했지만 v5로 가면서 해당 함수는 deprecated 되었습니다.

    정말 다이나믹한 효과를 누릴 수 있는 편이 아니라면 되도록이면 바닐라로 가는 게 좋은 것 같아요.

    댓글

Designed by Tistory.