React-query,Router, FramerMotion을 사용하여 영화 사이트를 만들었다.
Header.tsx안에 Home, Comming, Now 컴포넌트를 넣어 해당 페이지로 이동할때마다 Title아래에 Circle이 생기도록 작업하였다.
이때 useMatch를 사용하여 url이 true면 Circle을 추가하여 작업했는데 영화 클립시 팝업이 열리면서 url이 변경되어 Circle이 지워지는 문제가 발생하였다.
useMatch대신 useLocation을 사용하여 url의 주소를 받아온 뒤
home.pathname.split('movie')[0] movie의 앞자리만 반환하여 조건문을 사용하여 true면 Circle가 노출되도록 작업하였다.
const home = useLocation();
const result = home.pathname.split('movie')[0];
return (
<>
<HeaderWrap>
<Link to={'/'}>
POPULAR{result === '/' && <Circle layoutId="circle" />}
</Link>
<Link to={'/coming-soon'}>
Coming Soon
{result.includes('/coming-soon') && <Circle layoutId="circle" />}
</Link>
<Link to={'/now-playing'}>
Now Playing
{result.includes('/now-playing') && <Circle layoutId="circle" />}
</Link>
</HeaderWrap>
</>
);
스터디원들의 코드를 보면서 같은 결과물이지만 그 안의 코드가 정말 다르다고 느껴졌다.
그 중 두가지가 너무 인상 깊다.
//Search.tsx
//props로 searchText,setSearchText 를 받아온다.
function Search({
searchText,
setSearchText,
}: {
searchText: string;
setSearchText: React.Dispatch<React.SetStateAction<string>>;
}) {
function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
//검색한 input을 지워주는 역할
setSearchText('');
}
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
//onChange될때마다 value값이 들어간다.
setSearchText(e.target.value);
}
return (
<Form onSubmit={handleSubmit}>
<Input onChange={handleChange} value={searchText} />
</Form>
);
}
//List.tsx
const [searchText, setSearchText] = useState('');
<Search searchText={searchText} setSearchText={setSearchText} />
<Items variants={ItemsVariants} initial="hidden" animate="visible">
{movies
.filter((movie) => {
if (searchText) {
//movie(data) title안에 searchText 가 포함하고 있으면 그것을 리턴해 map으로 뿌려주고
return movie.title.includes(searchText);
} else {
// 아니라면 종료한다.
return true;
}
})
.map((movie) => (
<Movie key={movie.id} movie={movie} setMovieId={setMovieId} />
))}
const [id, setId] = useState(null);
<Card key={movie.id} movie={movie} onClick={() => setId(movie.id)} />
{id ? (
<Overlay
variants={overlayVariants}
initial="hidden"
animate="visible"
exit="exit"
>
<DetailCard id={id} onClick={() => setId(null)} />
</Overlay>
) : null}
이번 과제에서는 FramerMotion을 주로 썼는데 효과를 어디에 줘야하는지 혼란스러웠지만 삽질끝에 정확한 위치에 다들 들어간거 같아서 다행이다.
그리고 다른 사람들의 코드를 보면서 나와는 다른코드에 배울점이 많아보였다.
Search코드도 그렇고 팝업이 보이는것을 나는 location을 사용해 parameter에 있는 id값이랑 일치한다면 팝업이 보이게 했는데 그냥 카드에 아이디값 넘겨줘서 보일지 말지 구현하는것도 간단한 방법이라는것을 배웠다.
//내코드
const location = useLocation();
const { id } = useParams<{ id: string }>();
const isMatch = id && location.pathname.includes(id);