React + TS(useState, useRef, useCallback, Event Handler)

박정호·2022년 10월 31일
0

Game Project

목록 보기
11/13
post-thumbnail

🚀 Start

간단한 구구단, 끝말 잇기 게임을 구현해보면서 useState, useRef, useCallback, Event Hanlder는 어떻게 타이핑되는지 알아보자.

1️⃣ useState

useState를 사용할 때는 useState<타입>() 과 같이 Generics를 사용하여 해당 상태가 어떤 타입을 가지고 있는지 설정하면 된다.

  const [first, setFirst] = useState<number>(Math.ceil(Math.random() * 9));
  const [second, setSecond] = useState<number>(Math.ceil(Math.random() * 9));
  const [value, setValue] = useState<string>("");
  const [result, setResult] = useState<string>("");

✅ 참고로 useState를 사용할 때는 Generics를 사용하지 않아도 타입을 추론하기 때문에 생략해도 상관없다.

그렇다면 어떤 상황에서 Generics을 사용하는 것이 좋을까?

✅ 상태가 null일 수도 있고 아닐 수도 있는 상황에서는 Generics를 활용하면 좋다.

<Example>
type Information = { name: string; description: string };
const [info, setInformation] = useState<Information | null>(null);

✅ 상태의 타입이 까다로운 구조를 가진 객체이거나 배열일 때는 Generics 를 명시하는 것이 좋다.

<Example>
type Todo = { id: number; text: string; done: boolean };
const [todos, setTodos] = useState<Todo[]>([]);

💡 중요) useState에 빈 배열[]이 초기화되는 경우

useState 초기 값을 빈 배열로 할 경우, 타입스크립트에서는 빈배열[]never type으로 인식한다.

  • never type: 함수의 끝에 절대 도달하지 않는다는 의미를 지닌 타입

따라서 구체적인 타입을 지정해줘야 한다.

  • TryInfoInterface

2️⃣ useRef

useRef는 리액트 컴포넌트에서 외부 라이브러리의 인스턴스 또는 DOM 을 특정 값 안에 담을 때 사용된다. 추가적으로, 이를 통해 컴포넌트 내부에서 관리하고 있는 값을 관리할 때 유용한다.

👉 DOM 관리하기

ref를 사용 시 어떤 타입을 사용할지 헷갈리면 타입추론된 타입을 확인하면 된다.

useRef를 사용 할 땐 Generics 로 타입을 정한다.

useRef를 사용하여 DOM에 대한 정보를 담을 땐, 초깃값을 null 로 설정한다.

inputRef.current안의 값을 사용 하려면 null 체킹을 해주어야 한다.
즉, 특정 값이 정말 유효한지 유효하지 않은지 체크하는 것이다. 타입스크립트에서 만약 어떤 타입이 undefined 이거나 null 일 수 있는 상황에는, 해당 값이 유효한지 체킹하는 작업을 꼭 해주어야 자동완성도 잘 이루어지고, 오류도 사라진다.

👉 변수 값 관리하기

타입스크립트 환경에서 useRef 를 통해 어떤 변수 값을 관리하고 싶을 땐 다음과 같은 코드를 작성.

const id = useRef<number>(0);
  const increaseId = () => {
    id.current += 1;
  }

useRef 를 쓸땐 위와 같은 코드처럼 Generic 을 통해 ~.current 의 값을 추론 가능.


3️⃣ EventHandler

1️⃣ 이벤트 인자 타입을 지정하려면 먼저 이벤트의 타입을 찾는다.
2️⃣ 이벤트의 타입을 찾았다면, 해당 이벤트를 발생시키는 요소를 제네릭 인자로 전달한다.

👉 input 상태 관리하기

해당 코드에서는 onChangee 객체의 타입을 지정해야 한다.

하지만 e 객체의 타입이 무엇인지 외울 필요 없다. 왜냐하면 타입추론에 의해서 어떤 타입을 구현해야 할지 알려준다.

따라서, 다음과 같이 이벤트 타입과 제네릭을 지정할 수 있다.

👉 submit 상태 관리하기

submit 역시 다음과 이벤트 타입과 제네릭을 지정할 수 있다.

💡 이처럼 타입추론에 의해 설정이 간편하다.

✅ 그리고 ChangeEvent, FormEvent 이외에도 역할에 따른 여러 이벤트 타입이 존재한다.

✅ 또한, input Element, form Element 이외에도 여러 HTML 노드의 타입이 존재한다.


4️⃣ useCallback

useCallback은 메모제이션된 함수를 반한하는 하는 함수로, 특정 함수를 새로 만들지 않고 재사용하고 싶을 때 사용한다.

따라서, 앞서 본 Event Hanlder함수들useCallback으로 감싸주어서 불필요한 렌더링을 방지하고 성능을 최적화 한다.

✅ 이때 useCallback으로 한번 감싸줬기 때문에 타입 추론이 안된다. 즉, handleruseCallback으로 wrapping 하면 e가 type을 잃는다. 따라서 해결할 수 있는 방법은 2가지이다.

방법 1: event object에 직접 typing

const onChangeHandler = useCallback((e: React.FormEvent)=>{}, [])


방법 2 : useCallback의 generic 으로 typing

  • 단, generic은 가독성이 낮아진다.
const onChangeHandler = useCallback<(e: React.FormEvent) => void>((e)=>{}, [])


참조 및 참고하기 좋은 사이트

profile
기록하여 기억하고, 계획하여 실천하자. will be a FE developer (HOME버튼을 클릭하여 Notion으로 놀러오세요!)

0개의 댓글