front-end / / 2024. 3. 1. 20:23

[react] 타입스크립트에서 state 사용하기

이번에는 타입 스크립트와 State에 대해 알아보자. 아래 예제를 한번 보자.

const GuestList: React.FC = () => {
    const [name, setName] = useState("");
    const [guests, setGuests] = useState([]);

  const onClick = () => {
    setName("");
    setGuests([...guests, name]);
  };

  return (
    <div>
      <h3>Guest List</h3>
      <input value={name} onChange={(e) => setName(e.target.value)} />
      <button onClick={onClick}>Add Guest</button>
    </div>
  );
};

이 컴포넌트는 name과 guests를 state로 가지며 Add Guest 버튼을 클릭하면 guests에 추가하는 기능을 하는 컴포넌트이다. (여기서 Guest 출력 기능은 포함되지 않음)

하지만 setGuests에 타입이 지정되지 않아서 오류가 발생하는 것을 알 수 있다.

guests에 왜 오류가 발생할까?

이 문제의 해결을 위해서 타입스크립트를 적용해보자.

우리는 useState를 사용할 때 항상 기본값을 설정을 한다. 여기서 설정되는 기본값에 맞는 타입으로 타입스크립트는 변수의 타입을 결정한다. 위에서 name과 guests에 대한 state 변수를 사용했다. name의 타입은 기본값이 공백('')이라서 string으로 지정을 했다. 하지만 guests는 기본값이 빈 배열([])이라서 어떤 타입의 값이 배열에서 사용될 지 알 수가 없다. 단지 배열이라는 사실만 알 뿐이다. 그래서 타입스크립트에서는 never[]로 지정을 한다. 우리는 guests의 배열이 어떤 값으로 사용될 지 아래와 같이 알려줘야 한다.

const [guests, setGuests] = useState<string[]>([]);

이것은 guests의 데이터는 string[]이 사용될 것이라고 타입스크립트에서 말하는 것이다. 이렇게 하면 setGuests에서 발생한 오류는 없어진다.

또 다른 예제를 하나 보자.

이 예제는 사용자가 검색어를 입력하면 이름을 찾아서 검색결과를 출력해주는 컴포넌트이다.

const users = [
  { name: "Sarah", age: 20 },
  { name: "Alex", age: 20 },
  { name: "Michael", age: 20 },
];

const UserSearch: React.FC = () => {
  const [name, setName] = useState("");
  const [user, setUser] = useState();

  const onClick = () => {
    const foundUser = users.find((user) => {
      return user.name === name;
    });

    setUser(foundUser); // 오류
  };

  return (
    <div>
      User Search
      <input value={name} onChange={(e) => setName(e.target.value)} />
      <button onClick={onClick}>Find User</button>
      <div>
        {user && user.name}
        {user && user.age}
      </div>
    </div>
  );
};

여기서 발견되는 문제는 setUser(foundUser) 시 foundUser의 타입이 지정되지 않았다는 것이다. 또한 user.name 혹은 user.age를 출력해야 하는데 user의 타입이 지정되지 않아서 타입스크립트에서 오류가 발생한다.

[오류 내용]

이 오류 내용을 이해하기 위해서 아래 그림을 한번 보자.

컴포넌트가 처음 렌더링 되고 검색하기 전에는 user의 타입이 undefined로 지정된다. 그리고 사용자가 검색을 하고 사용자를 찾으면 user 타입이 name과 age를 가진 객체 타입으로 지정이 된다. 즉, 두 가지 타입이 user 타입으로 지정이 된다는 것이다.

이런 내용을 타입스크립트에서 적용하기 위해서 user의 useState에 제네릭(generic) 타입을 넣어야 한다.

const [user, setUser] = useState<{ name: string; age: number } | undefined>();

user에 마우스 오버를 해보면 아래와 같이 객체타입과 undefined 타입이 정의되는 것을 알 수 있다.

참고

https://www.udemy.com/course/react-and-typescript-build-a-portfolio-project

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유