랜덤송 같은 경우는 노래 종류도 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&&이라고 작성해 그 내용이 존재할때만 렌더링할 수 있도록 해주었다!
오늘의 일기:
매번 느끼는 거지만, 대체 어디까지를 컴포넌트로 만들어야 할지 그 기준을 정하는 것은 어려운 것 같다.
협업할 때도 여기에 대해 팀원들과 명확한 기준을 잡아본 적이 없어 그냥 다들 본인만의 기준으로 나누었던 것 같다...
오늘 같은 경우도, 파일 하나에 코드를 다 적은 다음에 너무 지저분한 것 같아 나눴는데, 애초에 명확한 기준을 잡고 나누는 게 나았을 거란 생각이 든다.
그래서 컴포넌트를 나누는 기준에 대해서도 이번 기회에 공부해 보았다.
프로젝트하면서 많이 배운다...!!

