TIL 57. TypeScript로 TodoList 리팩토링

isk·2023년 1월 18일
0

TIL

목록 보기
54/122
post-custom-banner

TypeScript를 사용해서 기존에 만들어놨던 TodoList를 리팩토링 하려고 한다.
redux-toolkit을 사용했으며, persist도 사용했다.

useAppSelector

const count = useSelector((state: RootState) => state.counter.value)

useSelector를 사용하면, useSelector를 사용하는 모든 곳의 state에 위 코드처럼 타입을 지정해줘야한다.

const count = useAppSelector((state) => state.counter.value)

하지만 타입을 미리 지정해주면 타입을 지정해줄 필요가 없다. (타입 추론 굿)

// configStore.ts

import { combineReducers, configureStore } from '@reduxjs/toolkit';

import storage from 'redux-persist/lib/storage';
import { persistReducer } from 'redux-persist';
import thunk from 'redux-thunk';

import todoReducer from '../modules/todo';

const persistConfig = {
  key: 'root',
  storage,
};
const rootReducer = combineReducers({
  todoReducer,
});

const postPersistedReducer = persistReducer(persistConfig, todoReducer);

const store = configureStore({
  reducer: {
    todoReducer: postPersistedReducer,
  },

  middleware: [thunk], // thunk 사용할 때
});

export default store;
// React에서 사용할 수 있도록 타입을 만들어 export 해준다.
export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof rootReducer>; // todoReducer: {todos: []}
// ReturnType은 <>속의 반환 타입으로 구성된 타입을 생성한다.

ReturnType은 <>속의 반환 타입으로 구성된 타입을 생성한다.

function fn(): { a: number; b: string };

type Type1 = ReturnType<() => string>;     
// type Type1 = string

type Type2 = ReturnType<(s: string) => void>;     
// type Type2 = void

type Type3 = ReturnType<<T>() => T>;     
// type Type3 = unknown

type Type4 = ReturnType<<T extends U, U extends number[]>() => T>;     
// type Type4 = number[]

type Type5 = ReturnType<typeof f1>;     
/*
type Type5 = {
   a: number;
   b: string;
}
*/
                    
type Type6 = ReturnType<any>;     
//type Type6 = any

type Type7 = ReturnType<never>;     
//type Type7 = never

// hooks.ts

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

// 일반적인 "useDispatch"와 "useSelector" 대신 앱 전체에서 사용하십시오
export const useAppDispatch: () => AppDispatch = useDispatch;
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

useSelector를 할당하고 TypedUseSelectorHook에 Generic Type을 받는 것 부분은 아래 예시를 보면 이해하는데 도움이 된다.

import { TypedUseSelectorHook, useSelector } from 'react-redux';

interface TypedUseSelectorHook<T> {
    name: T;
}

interface RootState {
    state: {
        text: string,
        isDone: boolean,
    } 
}
const useAppselector: TypedUseSelectorHook<RootState> = {name: {
    state: {
        text: 'a!',
        isDone: false,
    }
}}

export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

그리고 아래처럼 사용하면 된다.

const globalTodo = useAppSelector((state) => state.todoReducer.todos);
post-custom-banner

0개의 댓글