이 연습에서는 useState의 이상한 속성과 TypeScript가 이를 처리하는 방법을 살펴보겠습니다.

여기에는 같은 이름의 이전 컴포넌트와는 다른 Tags 라는 이름의 복잡한 컴포넌트가 있습니다.

interface TagState {
  tagSelected: number | null;
  tags: { id: number; value: string }[];
}

export const Tags = () => {
  const [state, setState] = useState<TagState>({
    tags: [],
    tagSelected: null,
  });
  return (
    <div>
    ...

useState 내부에는 tags 배열과 현재 nulltagSelected 값이라는 두 가지 상태 조각으로 캡처 되는 TagState 가 있습니다.

이것을 두 개의 다른 useState 로 나눌 수 있다고 생각할 수도 있지만, 이 경우에는 각 태그 위에 맵핑하고 그 안에 값이 있는 버튼을 만들기 때문에 한 곳에 유지하는 것이 더 편리합니다.

버튼을 클릭하면 태그를 선택할 수 있습니다. 현재 상태를 확인한 다음 새 상태를 반환하는 함수를 전달할 수 있는 setState API를 사용하고 있습니다.

return (
    <div>
      {state.tags.map((tag) => {
        return (
          <button
            key={tag.id}
            onClick={() => {
              setState((currentState) => ({
                ...currentState,
                // @ts-expect-error
                tagselected: tag.id,
              }));
            }}
          >
            {tag.value}
          </button>
        );
      })}

아래에는 onClick 을 사용하여 상태에 새 태그를 추가하는 또 다른 버튼이 있습니다.

...
    <button
        onClick={() => {
          setState((currentState) => ({
            ...currentState,
            tags: [
              ...currentState.tags,
              {
                id: new Date().getTime(),
                value: "New",
                // @ts-expect-error
                otherValue: "something",
              },
            ],
          }));
        }}
      >
        Add Tag
      </button>

Challenge

이 코드에 표시되지 않는 몇 가지 오류가 있을 것으로 예상됩니다.

첫 번째 버튼의 setState에서 tagSelected 키가 소문자로 작성되어 있는데, 이 키는 대문자로 작성되어야 합니다.

태그를 반환하는 두 번째 버튼의 함수에서는 원하는 모든 것을 전달할 수 있습니다.

여러분의 과제는 이 문제에 대한 해결책을 찾는 것입니다.

오류는 사라지지만 인체 공학적으로 좋지 않다는 점에서 간단한 해결책은 없다는 점에 유의해야 합니다.

잠시 사용해보시고 문제가 해결되지 않으면 해결 방법을 확인해 보세요.