useReducer에 TypeScript 유형을 추가하는 방법

useReducer는 React에서 애플리케이션의 복잡성 중 일부를 추상화하는 좋은 방법입니다.
이 게시물에서는 리듀서에 TypeScript 유형을 추가하고 디버깅 시간을 절약하는 방법을 보여드리겠습니다! 🥳

애플리케이션이 커짐에 따라 useState에서 useReducer로 이동하기 시작하면 앱의 복잡성이 일부 숨겨집니다. 그러나 올바른 입력이 없으면 dispatchuseReducer 기능을 오용하여 예기치 않은 오류가 발생할 수 있습니다.

이 감속기가 상태를 관리하는 로그인 양식이 있다고 상상해보십시오.

function authReducer(state, action) {
  switch (action.type) {
    case "success":
      return { success: true, username: action.value, error: "" }
    case "failure":
      return { success: false, username: "", error: action.value }
    default:
      throw Error()
  }
}


React 앱에서 이 감속기를 사용하는 방법은 다음과 같습니다.

const [state, dispatch] = useReducer(authReducer)

function submit(data) {
  try {
    const response = await axios.post("/api/login", { data });
    dispatch({
      type: "success",
      value: response.data.user,
    });
  } catch (error) {
    dispatch({
      type: "failure",
      value: error.message,
    });
  } 
}


이것은 작동하지만 유형을 사용하지 않으면 실수로 다음을 수행하는 것을 방지할 수 없습니다.

dispatch({
  type: "failure",
  value: response.data.user,
})


그렇기 때문에 가능한 한 빨리 리듀서에 유형을 도입하여 이러한 오류가 컴파일 타임에 포착되도록 하는 것을 좋아합니다. 우리의 예를 들어 봅시다:

type User = {
  id: string;
  username: string;
}

export type AuthState = {
  success: boolean;
  user: User | null;
  error: string;
}

export type AuthAction = {
  type: "success" | "failure";
  value: User | string;
}

export function authReducer(state: AuthState, action: AuthAction) {
  switch (action.type) {
    case "success":
      return { success: true, user: action.value, error: "" }
    case "failure":
      return { success: false, user: null, error: action.value }
    default: throw Error()
  }
}


지금 리듀서를 입력하는 동안 액션을 입력한 방식 때문에:

type AuthAction = {
  type: "success" | "failure";
  value: User | string;
}


잘못된 유형의 작업에 잘못된 값을 보내는 것은 여전히 ​​가능합니다. "성공"유형에 대한 오류 메시지:

dispatch({
  type: "success",
  value: "Something went wrong",
})


따라서 유형이 허용하는 특정 값에 대해 좀 더 구체적으로 살펴보겠습니다.

type AuthAction =
  | {
    type: "success";
    value: User;
  }
  | {
    type: "failure";
    value: string;
  }


이제 React 앱에 감속기 사용량을 입력해 보겠습니다.

import { Reducer } from "react";
import { authReducer, authState, AuthState, AuthAction } from './auth_reducer';

const [state, dispatch] = useReducer<
  Reducer<AuthState, AuthAction>
>(authReducer, authState)

function submit(data) {
  try {
    const response = await axios.post("/api/login", { data });
    dispatch({
      type: "success",
      value: response.data.user,
    });
  } catch (error) {
    dispatch({
      type: "failure",
      value: error.message,
    });
  } 
}


이제 잘못된 값으로 "성공"유형을 호출하려는 경우:

dispatch({
  type: "success",
  value: "Something went wrong",
})


TypeScript에서 다음 오류가 발생합니다.

Type 'string' has no properties in common with type 'User'.


축하합니다. 리듀서에 TypeScript 유형을 추가하여 더 탄력적이고 사용하기 쉽게 만들었습니다! 🙌

좋은 웹페이지 즐겨찾기