[8일차] 랜덤송 나타내기

h-a-n-a·2023년 8월 14일

💫Ed Sheeran

목록 보기
8/24

랜덤송 같은 경우는 노래 종류도 6가지밖에 안되어서 그냥 프로젝트 내 간단하게 songs.ts 파일을 만들어 랜덤 함수를 돌렸다.

//songs.ts
const songs = [
  {
    title: "Hearts don't break around here",
    album: '÷ (Divide)',
    lyrics:
      "I feel safe when you're holding me near. \nLove the way that you conquer your fear",
    url: '/images/hearts.jpg',
    background: '#7EC9EB',
    details:
      '÷(2017)의 여덟 번째 수록곡으로, 당시 여자친구이자 현재 아내인 체리 시본(Cherry Seaborn)을 위해 작곡한 곡입니다.',
  },
  {
    title: 'Thinking out loud',
    album: 'X(Multiply)',
    lyrics:
      "Darling I will be loving you 'til we're 70. \nAnd my heart could still fall as hard at 23.",
    url: '/images/loud.webp',
    background: '#69B75A',
    details:
      '두 번째 정규 앨범 X(2014)에 열한번째 수록된 노래입니다.  ',
  },
  {
    title: 'Photograph',
    album: 'X(Multiply)',
    lyrics: "And if you hurt me That's OK, baby, \nonly words bleed",
    url: '/images/photograph.jpeg',
    background: '#1DD45A',
    details:
      '두 번째 정규 앨범 X(2014)에 수록된 곡으로, 시런이 너무 바쁜 스케줄로 인해 집에 잘 돌아가지 못하던 장거리 연애 때 당시 여자친구를 위해 만든 곡입니다.'
  },
...
export default songs;
//Playlist.tsx
function Playlist() {
  const [isClicked, setIsClicked] = useState(false);
  const [randomSong, setRandomSong] = useState({
    title: '',
    album: '',
    url: '',
    lyrics: '',
    background: '',
    details: '',
  });
  const handlePauseBtn = () => {
    setIsClicked(!isClicked);
  };
  const getRandomNumber = () => {
    const randomIndex = Math.floor(Math.random() * songs.length);
    return songs[randomIndex];
  };

  useEffect(() => {
    setRandomSong(getRandomNumber());
  }, []);

예전에도 랜덤함수를 이용해 랜덤배경이미지를 만든 적이 있었는데, 그 때는 return 값이 아마 hex color (string) 이었던 걸로 기억한다.

이번에는 getRandomNumber로 객체 값 자체를 리턴해서 다시 그걸 state로 만드는 거였고, 리턴된 값을 바로 컴포넌트 안에 {radomSong.title}, {rnadomSong.album} 등으로 꽂아주기만 됐다.

컴포넌트가 너무 많아지다 보니, 노래에 대한 설명은 <SongDetails {...{ randomSong }} /> 으로 전달해서 다시 SongDetails 안에서 풀어나갔다!

import { RandomSongProps } from '../Playlist';
import * as S from './style';

interface SongDetailProps {
  randomSong: RandomSongProps;
}

function SongDetails({ randomSong }: SongDetailProps) {
  return (
    <S.SongInfoContainer>
      {randomSong && <S.SongLyrics>{randomSong.lyrics}</S.SongLyrics>}
      {randomSong && (
        <S.SongDetailsWrapper>{randomSong.details}</S.SongDetailsWrapper>
      )}
    </S.SongInfoContainer>
  );
}

export default SongDetails;

randomSong의 초기 상태는 빈 객체로 시작했기 때문에, randomSong이 빈 객체로 전달된다면 해당 속성들이 다 텅텅 비어있기 때문에 런타임 에러가 발생할 수 있다. 그렇기 때문에 randomSong&&이라고 작성해 그 내용이 존재할때만 렌더링할 수 있도록 해주었다!


오늘의 일기:
매번 느끼는 거지만, 대체 어디까지를 컴포넌트로 만들어야 할지 그 기준을 정하는 것은 어려운 것 같다.

협업할 때도 여기에 대해 팀원들과 명확한 기준을 잡아본 적이 없어 그냥 다들 본인만의 기준으로 나누었던 것 같다...

오늘 같은 경우도, 파일 하나에 코드를 다 적은 다음에 너무 지저분한 것 같아 나눴는데, 애초에 명확한 기준을 잡고 나누는 게 나았을 거란 생각이 든다.

그래서 컴포넌트를 나누는 기준에 대해서도 이번 기회에 공부해 보았다.

프로젝트하면서 많이 배운다...!!


오늘의 작업물

profile
하루하루가 연습이니 내일은 더 강해질 겁니다

0개의 댓글