개요

리액트에 훅이 추가(리액트 16.8 버전)되기 이전에는 클래스 컴포넌트에서만 상태를 가질 수 있었다.

클래스 컴포넌트에서는 componentDidMount, componentDidUpdate와 같이 하나의 생명주기 함수에서만 상태 업데이트에 따른 로직을 실행시킬 수 있었다.

간단한 형태의 컴포넌트에서는 문제가 없으나, 프로젝트 규모가 커지면서 상태를 스토어에 연결하거나 비슷한 로직을 가진 상태 업데이트 및 사이드 이펙트 처리가 불편해졌다.

또한 모든 상태를 하나의 함수 내에서 처리하다 보니 관심사가 뒤섞이게 되었고 상태에 따른 테스트나 잘못 발생한 사이드 이펙트의 디버깅이 어려워 졌다.

리액트 훅이 도입되면서 함수 컴포넌트에서도 클래스 컴포넌트와 같이 컴포넌트의 생명주기에 맞춰 로직을 실행할 수 있게 되었다. 이에 따라 비즈니스 로직을 재사용하거나 작은 단위로 코드를 분할하여 테스트하는 게 용이해졌으며 사이드 이펙트와 상태를 관심사에 맞게 분리하여 구성할 수 있게 되었다.

useState

funjction useState<S>(
	initialState: S | (() => S)
): [S, Dispatch<SetStateAction<S>>];

type Dispatch<A> = (value: A) => void;
type SetStateAction<S> = S | ((prevState: S) => S);

useState가 반환하는 튜플

튜플의 첫 번째 요소는 제네릭으로 지정한 S타입

두번째 요소는 상태를 업데이트할 수 있는 Dispatch 타입의 함수.

Dispatch 함수의 제네릭으로 지정한 SetStateAction에는 useState로 관리할 상태 타입인 S 도는 이전 상태 값을 받아 새로운 상태를 반환하는 함수인 (prevState: S) ⇒ S가 들어갈 수 있다. 이처럼 useState를 동기적으로 처리하기 위해 사용한다.

useState에 타입스크립트를 적용하면 강력한 힘을 가지게 된다.