[REACT] 음악 추천 사이트 만들기

김재즈·2023년 12월 10일
1

인터페이스 제작

마지막 결과물을 다시 한번 봅시다.

어우.. 처참하죠?

정리좀 해줍시다.

컴포넌트 제작

API 받아오는 컴포넌트, 인터페이스로 코드를 구분해줄게요.

GET API Component

const fetchPlaylists = async (query: Props) => {
  
  try {
    getAccessToken();
    const token = window.localStorage.getItem('token');
    console.log(token);
    const response = await axios.get(`https://api.spotify.com/v1/playlists/${query.id}`, {
      params: {
        limit: query.limit,
        sort: 'popularity',
        
      },
      headers: {
        Authorization: `Bearer ${token}`,
      },
    });

    const data = response.data.tracks.items.slice(0,query.limit);
  
    return data;
  } catch (error) {
    console.error('Error fetching data from Spotify API:', error);
    throw error;
  }
};

useQuery를 사용하기 위해서 저번 코드를 이쁘게 다져줬다.


search 기능으로는 도저히 찾아봐도 인기 차트같은걸 가져올 수 없어서.
그냥 플레이리스트를 가져오기로 나 자신과 타협했다.

플레이리스트 API는 가져오려는 플레이리스트의 ID가 필요한데,
그걸 props로 받아주기로 했다.

interface Props {
  limit: number;
  title: string;
  id: string;
}

저번에 배운 interface를 활용해서 props를 받아와준 모습.

const response = await axios.get(`https://api.spotify.com/v1/playlists/${query.id}`, {
      params: {
        limit: query.limit,
        sort: 'popularity',
      },
      headers: {
        Authorization: `Bearer ${token}`,
      },
    });

이렇게 query props를 이용해 API를 받아와준다.

const data = response.data.tracks.items.slice(0,query.limit);
return data;

props로 limit를 받아와준다.
이렇게 data를 slice해주면 받아온 50개의 데이터중 원하는 만큼만 출력이 가능하겠죠?


인터페이스

받아온 데이터들을 출력하기 위해 인터페이스를 꾸며줬다.
바로 차크라를 이용했따!

차크라 UI가 진짜 생각보다 너무 간편하고 좋더라.

우선 useQuery를 이용해서 로딩중, 에러, 성공의 경우를 나눠줄 수 있었다.

const { data: playListResult, isLoading, isError } = 
useQuery(['playlists', query], () => fetchPlaylists(query));
 {isLoading ? (
  ) : isError ? (
  ) : ()

이렇게 말이다!


로딩창

해서, 로딩중일 때는 뭔가 간지나게 해보고 싶었다.
그래서 찾아보다가 차크라 UI에 Skeleton 이라는걸 찾게 되었는데,

아니 이거 gif 안올라가?

암튼 그 회색 번쩍번쩍 하는거임.
여기 들어가면 확인가능.

그래서 이걸 사용해서 로딩창을 만들어줬다.

	  <Stack>
        <Skeleton h="50px" w="300px" />
        <Flex w="100%" justify="space-between">
          {Array(5).fill(null).map((_, index) => (
            <AspectRatio key={index} ratio={1} flex="1" m={5}>
              <Skeleton w="100%" h="100%" />
            </AspectRatio>
          ))}
        </Flex>
      </Stack>

여기서 잠깐 보고갈 부분은

Array(5).fill(null)

이 부분인데, 이렇게 사용하면 map을 사용하지 않고
원하는 횟수 만큼 컴포넌트를 반복시킬 수 있다!

결과

짜란~


결과창

결과창 기능은 아래처럼 했다.

  • (앨범 커버사진, 제목, 가수) 이렇게 표시를 하고
  • 페이지 크기에 따라 보여지는 개수가 다르게.
  • 초과된 데이터는 가로 스크롤에 묻히도록.
  • 페이지 크기에 맞춰 가로에 데이터를 꽉 채우도록.

이렇게 짠 코드는

		<Stack>
          <Heading>{query.title}</Heading>
          <Flex overflowX='auto'>
            {playListResult?.map((track: Tracks) => (
              <Box key={track.track.album.id} p={5} pt={0} w={['100%', '50%', '33.33%', '25%']} flexShrink="0">
                <Image src={track.track.album.images[0].url} alt="Album Cover" w="85%" h="85%" objectFit="cover" />
                <Text noOfLines={1} fontSize="lg">{track.track.name}</Text>
                <Text noOfLines={1} color="gray" fontSize="sm">{track.track.album.artists[0].name}</Text>
              </Box>
            ))}
          </Flex>
        </Stack>

이런 느낌으로 짰다.

여기서 볼 부분은

w={['100%', '50%', '33.33%', '25%']}

해당 코드를 통해 페이지 크기에 따라 한 박스의 크기를 조절해줬다.

<Flex overflowX='auto'>

해당 코드를 통해 가로 스크롤을 사용했다.

이렇게 만든 결과 창은..!!!!

짜란~~~
이렇게 깔끔하게 만들어 줄 수 있었다!!

다크모드 하면 더 이쁨.

이야~

다음 글에서는 앨범 클릭했을 때 보여지는 Detail 창을 만들어보기 시작할게요~

profile
개발의 천재

1개의 댓글

comment-user-thumbnail
2023년 12월 11일

슬슬 모습이 갖춰지는고만... 박수드립니다 짞짞짞

답글 달기