본문 바로가기

main/React

[TypeScript] REST API로 받아온 데이터 일부만 Props로 넘겨주기

API로 받아온 데이터가 뭉탱이라 컴포넌트별로 분리해서 Props를 보내주고 싶었다.

근데 타입스크립트 문법을 아직 잘 몰라서 계속 에러 발생..,, 

Type 'PlayInfo | undefined' is not assignable to type 'PlayInfo'.
  Type 'undefined' is not assignable to type 'PlayInfo'.ts(2322)
PlayList.tsx(22, 3): The expected type comes from property 'info' which is declared here on type 'IntrinsicAttributes & IProps'


Type '{ props: PlayInfo | undefined; }' is not assignable to type 'IntrinsicAttributes & IProps'.   
  Property 'props' does not exist on type 'IntrinsicAttributes & IProps'.


Type '{ description?: string | undefined; external_url?: string | undefined; image?: { url: string; width: number; height: number; } | undefined; comments?: { total: number; items: []; } | undefined; }' is not assignable to type '{ description: string; external_url: string; image: { url: string; width: number; 
height: number; }; comments: { total: number; items: []; }; }'.
  Types of property 'description' are incompatible.
    Type 'string | undefined' is not assignable to type 'string'.
      Type 'undefined' is not assignable to type 'string'.

뭐 이런 에러들이 계속 나옴.. 한참을 삽질했다.


먼저, 컴포넌트에 내려 줄 Props 타입은 다음과 같다.

type IProps = {
  playInfo?: {
    description: string;
    external_url: string;
    image: {
      url: string;
      width: number;
      height: number;
    };
    comments: {
      total: number;
      items: [];
    };
  };
};

 

그리고 부모 컴포넌트에서,

const PlayListPage = () => {
  const [playListInfo, setPlayListInfo] = useState<IProps["playInfo"] | undefined>();
  
  useEffect(() => {
    Axios.get("").then((res) => {
      const resData = res.data.data;
      const playListData: IProps["playInfo"] = {
        description: resData.description,
        external_url: resData.external_url,
        image: {
          url: resData.image.url,
          width: resData.image.width,
          height: resData.image.height,
        },
        comments: {
          total: resData.comments.total,
          items: resData.comments.items,
        },
      };
      setPlayListInfo(playListData);
    });
  }, []);
  
  return (
    <>
      <PlayList playInfo={playListInfo} />
    </>
  );
};

export default PlayListPage;

types를 선언해주고,

State에 IProps의 playInfo 타입으로 객체를 만들어 주고,

Axios 데이터 받아오면서 필요한 부분만 playListData에 담고, setState 해주었다.

그리고 하위 컴포넌트에 playInfo라는 이름으로 넘겨주었다.

 

props를 받는 자식 컴포넌트에서는,

const PlayList = ({ playInfo }: IProps) => {
  console.log(playInfo?.description);
  ...
}

마찬가지로 types를 선언해주고, 

playInfo를 IProps에서 꺼내 받아왔고 코드에서 playInfo로 바로 사용할 수 있었다.

그런데 자식 컴포넌트에서는 playInfo의 하위 속성들을 가져올 때 ?가 붙는다. 

자식 컴포넌트라서 playInfo가 존재하지 않을 수도 있음을 표현해줘야 하는 것 같다.

 

그럼 이제 이렇게 필요한 데이터만 받아볼 수 있음 ^___^