-
useQuery GET으로 받은 데이터가 props로 전달되지 않을 경우Studying/React 2023. 7. 10. 11:54
문제 발생
Portfolly 프로젝트에서 '포트폴리오 상세보기 페이지'를 만들던 중 발생한 문제입니다.
특정 포트폴리오를 클릭했을 때, react-query의 useQuery로 해당 포트폴리오 데이터를 GET 요청하도록 만들었습니다. 그런 다음 서버가 준 데이터(작성자, 작성 날짜, 작성 글, 좋아요 수, 북마크 여부 등...)에 따라 화면을 그리게 만들었습니다.
그런데 좋아요 버튼 컴포넌트 LikeBtn에 인자로 전달하는 좋아요 수(data.likes) 등이 true임에도 그 값이 전달되지 않는 문제가 발생했습니다. 이렇게되면 사용자가 이전에 '좋아요' 한 게시물임에도 하트 아이콘에 표시가 안됩니다.
렌더링 순서로 인한 props가 미전달 문제인가 싶어서 렌더링 순서를 콘솔에 찍어보았습니다.
export default function PortfolioDetail() { console.log('PortflioDetail.tsx 렌더링 시작') const navigate = useNavigate(); const { portfolio_id } = useParams(); let user: User = { member_id: 0, name: '', picture: '' } const { data, isSuccess } = useQuery(['portfolio', portfolio_id], () => call(`/portfolios/${portfolio_id}`, 'GET')); if (isSuccess) { console.log('GET(useQuery)') user = { member_id: data.member_id, name: data.name, picture: data.picture } } return ( console.log('PortfolioDetail.tsx 컴포넌트 렌더링') ); }
결과는 아래와 같았습니다.
1. PortfolioDetail 렌더링 시작(컴포넌트가 호출되어 로드&컴포넌트 내부 함수 수행)
2. useQuery로 GET 요청 완료
3. PortfolioDetail 컴포넌트 렌더링 시작(return() 함수 실행을 의미)
따라서 컴포넌트가 렌더링 될 때 GET 요청을 완료한 바이니 props값이 전달되지 않는 문제는 발생하지 않는 거 같았습니다.
원인
useQuery의 두 번째 인자인 콜백 함수는 useEffect와 마찬가지로 렌더링 이후에 실행됩니다. 따라서 첫 렌더링 때에는 props에 넘겨줄 값이 없기 때문에 data.likes 등의 값이 전달되지 못한 것입니다.
위에서 콘솔에 찍을 때 콜백 함수 호출을 찍었어야 했던 것 같습니다.
마치 useState에 초기값을 정의하지 않을 시 undefined 에러가 뜨는 것과 비슷한 것 같습니다. useState는 비동기로 작동하기 때문에 페이지가 그려지기 전까지 undefined를 가지고 있다가 페이지가 그려진 후 필요한 state를 넣어주기 때문입니다.
해결 방법
아래와 같이 && 연산자를 사용하여 isSuccess일 때 좋아요, 북마크 버튼이 렌더링 되도록 바꾸었습니다.
{isSuccess && <> <LikeBtn portfolio_id={data.portfolio_id} lastestLikes={data.likes} nowIsLike={data.isLike} /> <Bookmark /> </> }
혹은 타입스크립트의 새로운 문법으로 data?.portfolio_id 와 같이 처리할 수도 있겠습니다.
또는 useQuery의 suspense를 사용하면 그러한 구문들을 사용하지 않고도 '데이터가 없는 상황을 고려하지 않게' 만들 수 있다고 합니다. useQuery를 통해 데이터가 완전히 받아와지지 않았다면 컴포넌트 자체를 mount하지 않아 데이터가 존재하지 않는 상황이 아예 발생할 수 없도록 구성하는 것입니다.
참고 사이트
1. 훅 플로우에 관련하여
2. react-query에 관하여
3. 그 외
'Studying > React' 카테고리의 다른 글
Warning: React does not recognize the ` ` prop on a DOM element (0) 2023.07.12 React quill Editor + react-hook-form feat.TypeScript (0) 2023.07.11 [Custom Hook] return하는 데이터 타입이 전부 유니온으로 합쳐지는 경우 (0) 2023.07.09 API 요청 코드 분리하기(일반 함수 vs 커스텀 훅) (0) 2023.07.06 [Storybook] Storybook + Twin.macro 환경 설정 (0) 2023.07.01