-
[Custom Hook] return하는 데이터 타입이 전부 유니온으로 합쳐지는 경우Studying/React 2023. 7. 9. 16:15
문제 발생
Portfolly 프로젝트에서 좋아요 버튼을 위한 useLikeBtn 커스텀 훅을 만들다가, return 하는 데이터 값의 타입이 전부 union으로 합쳐지는 문제가 발생했습니다.
(React + TypeScript)
기억이 안 나서 대충 적어보자면 대략 아래와 같은 커스텀 훅이 있습니다.
const useLikeBtn = (initialValue: boolean) => { const [islike, setIsLike] = useState(initialValue); ... return [value1, value2, value3]; // 각각 타입이 string, number, boolean 이라고 가정 }커스텀 훅을 다른 코드 파일에서 호출한 다음 리턴값 value1을 받으려 하면, 다음과 같은 에러를 마주합니다.
'string | number | boolean' 형식은 (원래 받아야 할 value1 타입)형식에 할당할 수 없습니다. ts(2322)
원인: as const로 상수화 해야한다.
현재 리턴 형태는 배열입니다. 따라서 return 값의 타입이 (string | number | boolean)[] 형태로 되어있던 것입니다.
그 말은 즉슨 value1, value2, value3를 각각 별도 타입으로 반환받지 못하고, string | number | boolean 세 가지 경우를 모두 가질 수 있는 값으로 받게됩니다.
이를 별개로 나누어 받으려면 타입을 상수화 시켜야 합니다.
상수화란, TypeScript에게 특정 값이 변경되지 않을 것임을 알려주는 것입니다.
객체의 모든 필드를 readonly로 만들고, 배열을 readonly로 만들며, 리터럴 값은 그 값 자체를 하나의 타입으로 추론합니다.
// 상수화 하지 않을 경우 let str = "literal"; // type: string // 상수화 할 경우 let str = "literal" as const; // type: "literal" const arr = ["a", "b"] as const; // type: readonly ["a", "b"] const obj = {name: "alldone"} as const; // type: {readonly name: "alldone"}이로써 타입 추론이 더욱 정확하게 이뤄지게 됩니다.
해결 방법
return문 끝에 as const 를 붙여주면 됩니다.
return [value1, value2, value3] as const;그 다음 마우스를 hover 하여 return 값의 타입을 확인하면 아래와 같습니다.
type const = readonly [string, number, boolean]이렇게 상수화를 하면 리턴 값을 받을 때 value1, value2, value3를 각각의 타입으로 받을 수 있습니다.
더하여: Custom Hook에서 여러개 값을 return하는 방법
위에서 저는 return 값을 배열로 받았습니다.
당시에는 그냥 커스텀 훅을 처음 배울 때 본 예시 코드에서 배열로 쓰길래 쭉 그렇게 써왔는데, 문득 커스텀훅 외에는 객체를 보편적으로 사용하지 않나 싶어 그 차이를 알아봤습니다.
Custom Hook에서 여러개 값을 반환하는 방법에는 두 가지가 있습니다.
- array 형태
- object 형태
코드로 보면 아래와 같습니다. 어떤 경우에 두 가지 중 뭘 사용해야 하는지에 대해 정해진 건 없지만, 두 타입의 장단점을 알아보고 사용하면 좋습니다.
const [one, two] = useNumbers(); const { a, b, c } = useAlphabet();1. Array로 return하는 경우
const [color, setColor] = useState('Salmon'); const [age, setAge] = useState('5');아래와 같은 상황에서 array로 return하면 좋습니다.
- 적은 수의 값들을 return하는 경우
- 같은 컴포넌트 내에서 한 번 이상 사용하는 경우
array로 리턴값을 넘겨줄 경우 항목 순서를 반드시 지켜야 한다는 단점이 있습니다. 하지만 object보다 변수를 변경하기 간편해 자유롭게 변수명을 설정해서 사용할 수 있습니다. (커스텀 훅은 아니지만) 가장 대표적으로 useState처럼요.
2. Object로 return 하는 경우
const { value1, value2, value3, value4 } = useCustomHook()아래와 같은 상황에서 array로 return하면 좋습니다.
- 많은 수의 값들을 return하는 경우
- 한 컴포넌트 내에서 한 번만 사용하는 경우
Object는 배열처럼 순서를 기억할 필요가 없으며, 필요한 항목만 가져올 수 있어서 항목이 많은 경우에 사용하기 편합니다. 하지만 항목을 바꿀 때는 { value: data } 같은 형식으로 인해 배열보다 불편하다는 단점이 있습니다.
이렇게 보니 좋아요 버튼 훅 또한 Object 형식으로 리턴하는게 더 좋겠습니다.
참고 사이트
useInput을 typescript에서 사용하고 싶은데 - 인프런 | 질문 & 답변
강사님께 useInput 커스텀훅을 배웠는데, 굉장히 사용감이 좋아서 다른 react파일에서도 자주 사용하고 있었는데요 제가 이걸 typescript 프로젝트에서도 사용하고 싶은데, 제가 아직 typescript를 공부
www.inflearn.com
Typescript에서 효과적으로 상수 관리하기
const assertion and enum
blog.toycrane.xyz
타입스크립트 - 배열의 값을 타입(union)으로 바꾸기(const assertions)
2019/12/27 - [Typescript] - 더 나은 타입스크립트 작성하기 1 - Skills에 이어, Skill적인 부분이다. 하지만 이것을 알기 전에 먼저 const assertions에 대한 개념을 알아야한다. const assertions const assertions은 Types
code-masterjung.tistory.com
[React] Custom hooks의 return value
Custom Hook에서 여러개의 값을 return하는 방법은 두가지가 있다. const [one, two] = useNumbers(); const { a, b, c } = useAlphabet(); array형태와 object형태로의 return이다. 어떠한 경우에 array형태를 사용하고 object형
leego.tistory.com
'Studying > React' 카테고리의 다른 글
React quill Editor + react-hook-form feat.TypeScript (0) 2023.07.11 useQuery GET으로 받은 데이터가 props로 전달되지 않을 경우 (0) 2023.07.10 API 요청 코드 분리하기(일반 함수 vs 커스텀 훅) (0) 2023.07.06 [Storybook] Storybook + Twin.macro 환경 설정 (0) 2023.07.01 twin + styled 동적 할당 시 tw 사용이 불가능한 이유 (0) 2023.07.01