앞서 slice부분의 코드를 개선했다.
그럼 저장된 데이터들을 표현해줄 차례이다.
netflix(home).jsx에서 dispatch해 slice에서 영화데이터를 저장소에 저장해주게 된다.
기존 코드에서는 useEffect를 이용해 getGenres와 fetchMovie를 디스패치한 후, useSelector를 이용해 장르와 영화들을 불러온다.
영화 데이터들을 Slider --> CardSlider --> Card로 데이터를 전달 전달 전달한다.
이런 것을 'drilling'이라고 하는데
이 전에 들었던 강의에서 리덕스를 사용하는 이유 중에 하나가
이런 drilling을 안하기 위해서라고 했다.
상위 컴포넌트에서 하위컴포넌트로 계속 데이터를 전달하는 것은 불필요한 작업이라고 생각했다.
넷플릭스.jsx에서 useEffect로 영화 데이터를 fetch했으면 그 부분이 이미 저장소에 저장되어있을테니 굳이 넷플릭스.jsx에서 props로 데이터를 전달해주지 않고 slider에서 바로 불러와도 같은 결과를 가져오지 않을 까 하는 생각이 들어 chat Gpt의 도움을 받아 이 부분을 수정해보기로 했다.
기존 코드
const Netflix = () => {
const navigate = useNavigate();
const dispatch = useDispatch();
const genres = useSelector((state) => state.movie.genres);
//수정할 부분
const movies = useSelector((state) => state.movie.movies);
//수정할 부분
const genresLoaded = useSelector((state) => state.movie.genresLoaded);
// 장르를 불러오기
useEffect(() => {
dispatch(getGenres());
console.log("selectGenresLoaded", genresLoaded);
}, []);
// 영화 가져오기
useEffect(() => {
//수정할 부분
if (genresLoaded) dispatch(fetchMovies({type: 'all'}));
}, []);
console.log("movies", movies);
return (
<Container>
<Hero>
{/* Hero 컴포넌트의 코드... */}
</Hero>
//수정
<Slider movies={movies} />
</Container>
);
};
const Slider = () => {
const movies = useSelector((state) => state.movie.movies);
// Slider 컴포넌트의 나머지 코드...
};
const Netflix = () => {
const navigate = useNavigate();
const dispatch = useDispatch();
const genresLoaded = useSelector((state) => state.movie.genresLoaded);
// 장르를 불러오기
useEffect(() => {
dispatch(getGenres());
}, []);
// 영화 가져오기
useEffect(() => {
if (genresLoaded) dispatch(fetchMovies({ type: 'all' }));
}, [genresLoaded]);
return (
<Container>
<Hero>
{/* Hero 컴포넌트의 코드... */}
</Hero>
<Slider /> {/* movies를 props로 전달하지 않음 */}
</Container>
);
};
수정 후 동일한 결과를 가져왔다.
genresLoaded로 상태 변경을 감지하는 대신 어차피 가져온 genres의 상태로 genres가 로드된 경우에만 영화를 가져오도록 변경
genres.length로 fetchMovies를 하면 slice에도 굳이 genresLoaded가 없어도 됨.
const Netflix = () => {
// 코드 생략...
const dispatch = useDispatch();
const genres = useSelector((state) => state.movie.genres);
useEffect(() => {
dispatch(getGenres());
}, []);
useEffect(() => {
if (genres.length > 0) {
dispatch(fetchMovies({ type: 'all' }));
}
}, [genres]);
//코드 생략...
};