TypeScript - 리덕스 모듈 리팩토링

Seung min, Yoo·2021년 5월 5일
0
post-thumbnail

typesafe-action

이 라이브러리를 사용하면 타입스크립트를 사용할 때 액션생성함수와 리듀서를 더 깔끔하게 작성할 수 있게 된다.

  1. typesafe-actions를 사용하면 더이상 as const를 써주지 않아도 된다.
  2. method-chaining 방식을 사용한다면 문자열타입대신에 액션생성함수를 넣어도 작동한다는 것이다.

// counter.tsx
import {  createAction, ActionType, createReducer } from 'typesafe-actions';

const INCREASE = 'counter/INCREASE';
const DECREASE = 'counter/DECREASE';
const INCREASE_BY = 'counter/INCREASE_BY';

export const increase = createAction(INCREASE) ();
export const decrease = createAction(DECREASE) ();
export const increaseBy = createAction(INCREASE_BY)<number>();


type CounterState = {
    count: number;
};

const initialState: CounterState = {
    count: 0
}

const actions = { increase, decrease, increaseBy};
type CounterAction = ActionType<typeof actions>;

const counter = createReducer<CounterState, CounterAction>(initialState, {
    [INCREASE] : (state) => ({ count: state.count + 1 }),
    [DECREASE] : (state) => ({ count: state.count - 1 }),
    [INCREASE_BY] : (state, action) => ({ count: state.count + action.payload})
});

//Reducer을 method chaining 방식으로도 지원한다 그에 대한 예시 밑에
// const counter = createReducer<CounterState, CounterAction>(initialState)
// .handleAction(INCREASE, state => { count: state.count + 1}))
// .handleAction(DECREASE, state => { count: state.count - 1}))
// .handleAction(INCREASE_BY, (state , action ) => ({
//     count: state.action + action .payload
// }));
//이로 인해서 얻을 수 있는 장점은 액션의 문자열 타입 대신에 액션생성함수를 넣어도 작동한다는 것이다.

// function counter (state: CounterState = initialState, action: CounterAction): CounterState {
//     switch(action.type) {
//         case INCREASE:
//             return {count: state.count + 1};
//         case DECREASE:
//             return {count: state.count - 1};
//         case INCREASE_BY:
//             return {count: state.count + action.payload};
//         default:
//             return state;
//     }
// }


export default counter;

//todos.ts
import { action, ActionType, createAction, createReducer} from 'typesafe-actions'
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 = 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, {
    [ADD_TODO]: (state, action) => state.concat({
        ...action.payload,
        done:false
    }),
    [TOGGLE_TODO]: (state, action) => state.map(
        todo => todo.id === action.payload
        ? {...todo, done: !todo.done}
        : todo
    ),
    [REMOVE_TODO]: (state, action) => state.filter(
        todo => todo.id !== action.payload
    )    
})
// function todos (state: TodoState = initialState,
//                 action: TodosAction):TodoState {
//     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(todo => todo.id !== action.payload) 
//         default:
//             return state;
//     }
// }



export default todos;
profile
이제 막 개발을 시작한 프로그래밍 입문자

0개의 댓글