일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- js배열 알고리즘
- 실행컨텍스트
- jwt
- 테스트 코드 툴 비교
- gql restapi 차이
- 웹 크롤링
- 항해99 사전스터디
- 자바스크립트 엔진 v8
- toggle-btn
- FP 특징
- chromatic error
- 리덕스
- 타입스크립트
- 함수형 프로그래밍 특징
- 리액트
- 웹팩 기본개념
- 항해99 부트캠프
- this
- 항해99
- Js module
- 코어자바스크립트
- 항해99 미니프로젝트
- 렌더링 최적화
- 리액트 메모
- 리액트 렌더링 최적화
- 리액트 메모이제이션
- next js
- JS module system
- v8 원리
- 알고리즘
- Today
- Total
Jaeilit
custom hooks 와 typescript generic 사용하여 input hooks 만들기 본문
늘 잘 관리 된 프로젝트를 위해서 고민하고 노력하는 것을 즐기는데
인풋에 대해서 고민을 해봤다.
인풋은
로그인, 회원가입, 검색 등 input 을 다양한 곳에서 사용한다.
위에는 login page 라고 생각하고 email 과 password 2개의 input 을 만들어봤다.
위에서 필요한 속성은 label tag 를 제외하고
input 의 name 과 value 또 type 정도가 있을 수 있다.
handler fn 으로는 onChange, form 태그에 onSubmit 까지가 필수 속성일것 같다.
input tag 하나에 name, value, type, placeholder 는 동적으로 컨트롤 한다고 하더라도
onChage, onSubmit 정도는 custom hooks 으로 숨길 수 있지 않을까? 생각을 했다.
custom hooks 로 감싸보니 hooks 에 넘기는 타입을 지정하는 것에서 난관에 부딪혔다.
그래서 이것을 해결 한 것을 이야기 해보려고 한다.
input custom hooks 만들어보기
1. 인풋 UI 컴포넌트화 하기
일단 input 을 컴포넌트화 해본다. Props 속성들은 전부 Input element 가 가지고 있는 속성들을 확장(extends) 해서 가져온다.
2. useInputHooks 커스텀 훅 제작
사실 정말 별게 없다.
리액트를 1주일만이라도 배운 사람이라도 작성할 수 있고 어디서든 많이 보는 전형적인 교과서 같은 코드라고 생각한다.
하지만 여기서 주목 할 점은 params 로 받는 valueObj 인데 state 의 초기 값을 valueObj로 받아와서 onChage 안에서 값을 핸들링해준다.
valueObj의 타입은 string key 와 string 또는 number 가 올 수 있는 value 의 객체 타입인데 여기서 내가 문제를 직면한다.
그럼 내가 hooks 에서 초기 값으로 key value 객체를 넘겼는데 그러면 사용 할때 초기 값으로 넘긴 값을 그대로 사용하게 타입가드를 해줄 수 없을까?
3. 제네릭을 사용해보자
아래와 같이 email 과 password 를 login input 값으로 사용하고 싶은데
useInputHooks 는 { string : string | number } 객체를 받을거라고 타입을 가드해주지만 내가 email 과 password 를 보낼거라는 건 생각도 못하고 있으니 자동완성을 안해준다? 못해준다?
근래 1~2주 동안 어떤 타입의 객체를 넘겼을 때 받는 입장에서는 받은 값으로 초기 값을 자동으로 생성해줄수 없을까를 많이 고민했었는데,
여기서 힌트를 얻은게 제네릭과 extends 이다.
제네릭으로 타입에 자유(unkown)를 줄 수 있지만 반대로 extends 로 좁혀 줄 수 있다
간단히 T extends string 을 해버리면 T 는 사실 number 가 들어가도 되는 타입이였지만 T 는 string 으로 확장이 되버려서 string 속성만 가지게 된다.
4. 완성하기
먼저 제네릭으로 email 과 password 객체를 줘봤다.
지금은 완성형이라 에러가 표시되지 않지만 원래는 에러가 뜬다.
제네릭으로 지정한 T 값이 State의 제네릭으로 들어가서 valueObj 의 타입은 T 가 지정해준다.
T 는 string : string | number 객체 타입으로 extends 해준다.
5. 완성
Input_Login 으로 지정해놓은 타입이 자동완성으로 보이기 시작했다.
input 쪽에서도 제네릭을 받아줘야한다.
input 으로 name과 hooks 에서 return 한 value onChange 등을 넘겨줬다.
여기서 value 는 객체 타입이라는 걸 잊으면 안된다.
value 는 객체타입이니 초기에 Input Props 에 InputHTMLAttributes 에서 type error 가 발생한다.
이제는 value type 을 객체타입으로 overide 해줘야한다.
overide 는 typescript 의 Utils 의 Omit 으로 value 속성을 제거해주고 다시 interface 안에서 value 타입을 재정의 해주면 된다.
overide 한 value 속성도 어떤 타입의 객체가 올지 모르니 일단 제네릭으로 사용한다.
input 에서도 제네릭을 extends 해준다.
만약 이 과정을 하지 않는다면 value={value[name]} 부분에서 type error 가 발생한다.
value 를 value[name] 으로 받는 이유는
name 이 email 이면 value 객체에서 key 가 email 인 value를 보여주기 위해서다.
말을 잘 못해서 그렇지, 복잡하지 않다.
테스트, 네 잘된다고 합니다.
'TIL' 카테고리의 다른 글
대기시간(Latency) (0) | 2023.05.19 |
---|---|
array 중복제거 js (0) | 2023.05.19 |
Appollo Client 공식문서 캐시 + 캐시 맛보기(머지,리드) (0) | 2023.01.18 |
Next js Jest Test Setting (0) | 2023.01.08 |
Nextjs 13 CSS in JS 와 CSS Module 사용하기 (0) | 2023.01.08 |