살펴보기
React Router는 라우팅을 위한 강력한 도구입니다. 라우팅을 사용하면 애플리케이션의 구조를 분리하고, 사용자에게 다양한 페이지를 제공할 수 있습니다.
React Router DOM v6에 새로 생긴 기능인 loader를 활용하면 라우트와 관련된 데이터를 더 쉽게 관리할 수 있습니다. loader는 라우트의 데이터를 로드하기 위한 함수입니다. 이 함수에서 로드된 데이터는 useLoaderData와 useRouteLoaderData 훅을 사용하여 컴포넌트에서 사용할 수 있습니다.
이 글에서는 useLoaderData와 useRouteLoaderData의 차이점과 사용법에 대해 알아보겠습니다.
예제 코드
useLoaderData
useLoaderData는 라우트의 로더에서 로드된 데이터에 접근하는 데 사용되는 훅입니다. 로더는 라우트의 데이터를 로드하기 위한 함수입니다.
useLoaderData를 사용하려면 다음과 같이 로더를 라우트에 설정해야 합니다.
// MyRoute.routes.tsx
const router = createBrowserRouter([
{
path: "/my-route",
element: <MyComponent />,
loader: async ({ params }) => {
// 로드된 데이터를 반환합니다.
},
},
]);
// MyComponent.tsx
function MyComponent() {
const data = useLoaderData();
// data는 로더에서 로드된 데이터입니다.
}
useRouteLoaderData
useRouteLoaderData는 특정 라우트의 로더에서 로드된 데이터에 접근하는 데 사용되는 훅입니다.
useRouteLoaderData를 사용하려면 다음과 같이 라우트에 로더를 설정해야 합니다.
// MyComponent.routes.tsx
const router = createBrowserRouter([
{
path: "/my-route",
element: <MyComponent />,
loader: async ({ params }) => {
// 로드된 데이터를 반환합니다.
},
},
]);
// MyComponent.tsx
function MyComponent() {
const data = useRouteLoaderData("my-route");
// data는 /my-route 라우트의 로더에서 로드된 데이터입니다.
}
두 훅의 차이점
useLoaderData와 useRouteLoaderData의 주요 차이점은 다음과 같습니다.
- useLoaderData는 모든 라우트의 로더 데이터에 접근할 수 있지만, useRouteLoaderData는 특정 라우트의 로더 데이터에만 접근할 수 있습니다.
- useLoaderData는 라우트의 로더를 설정할 때 사용되는 함수의 반환 값을 사용합니다. useRouteLoaderData는 라우트의 경로를 사용합니다.
사용 적합성
useLoaderData 사용 적합성
중첩된 라우트에서 useLoaderData를 사용하는 경우:
- 현재 라우트의 데이터만 필요할 때.
- 상위 라우트의 데이터가 하위 라우트의 렌더링에 큰 영향을 미치지 않을 때.
- 각 라우트가 상대적으로 독립적이고, 자신의 loader에서 필요한 모든 데이터를 로드할 수 있을 때.
useRouteLoaderData 사용 적합성
useRouteLoaderData를 사용하는 경우:
- 중첩된 라우트 구조에서 상위 라우트의 데이터가 하위 라우트에 필요한 경우.
- 특정 라우트의 데이터가 다른 라우트에서도 재사용되는 경우.
- 라우트 간의 데이터 의존성이 높을 때.
useLoaderData vs useRouteLoaderData
예시 상황
Q: 중첩된 라우트에서도 useLoaderData를 사용하면 가장 가까운 라우트의 로더 데이터를 가져오는 것으로 알고 있는데, 그렇다면 중첩된 라우트에서는 useRouteLoaderData를 사용하는 것이 더 좋을까요?
Q: 상세 라우트에서 useLoaderData, useRouteLoaderData 둘 중에 결과 값은 똑같은데, 뭘 사용해야하나요?
Q: useRouteLoaderData hook이 특정 값의 데이터를 가져오니까 의미상 이게 더 맞는 것 같은데...
위 질문에 대한 고민을 해결하기 위해 아래와 같은 상황과 구조를 예시로 작성해 보았습니다.
Hooks 예시
- 주제: 블로그 포스트와 관련 댓글
- 이론: useRouteLoaderData가 적합한 상황의 예시를 들어 설명드리겠습니다. 특히, 이 훅은 중첩된 라우트 구조에서 상위 라우트의 데이터를 하위 라우트에서 접근할 필요가 있을 때 유용합니다.
- 상황: 블로그 웹사이트에서 각 블로그 포스트에 대한 상세 페이지가 있습니다. 이 페이지에는 블로그 포스트의 내용과 해당 포스트에 달린 댓글이 표시됩니다. 포스트와 댓글은 서로 다른 API 엔드포인트를 통해 로드됩니다.
- 구조:
- /blog/:postId - 블로그 포스트의 상세 내용을 보여줍니다.
- /blog/:postId/comments - 해당 포스트에 대한 댓글을 보여줍니다.
- 여기서 /blog/:postId/comments는 /blog/:postId의 하위 라우트입니다.
라우트 설정
const router = createBrowserRouter([
{
path: "blog/:postId",
element: <Post />,
loader: async ({ params }) => {
// 포스트 데이터 로드
return fetchPostData(params.postId);
},
children: [
{
path: "comments",
element: <Comments />,
loader: async ({ params }) => {
// 댓글 데이터 로드
return fetchCommentsData(params.postId);
},
},
],
},
])
컴포넌트 사용
Post 컴포넌트는 포스트 데이터를 표시하고, Comments 컴포넌트는 해당 포스트에 대한 댓글을 표시합니다. Comments 컴포넌트에서는 useRouteLoaderData를 사용하여 상위 라우트(/blog/:postId)의 로더 데이터에 접근할 수 있습니다.
// Post 컴포넌트
function Post() {
const postData = useLoaderData();
return (
<div>
<h1>{postData.title}</h1>
{/* 포스트 내용 */}
<Outlet /> {/* 여기서 Comments 컴포넌트가 렌더링됩니다. */}
</div>
);
}
// Comments 컴포넌트
function Comments() {
const commentsData = useLoaderData(); // 현재 라우트의 댓글 데이터
const postData = useRouteLoaderData("blog/:postId"); // 상위 라우트의 포스트 데이터
return (
<div>
<h2>Comments on {postData.title}</h2>
{/* 댓글 목록 렌더링 */}
</div>
);
}
이 예시에서 Comments 컴포넌트는 useRouteLoaderData를 사용하여 상위 라우트인 Post 컴포넌트의 로더에서 로드된 포스트 데이터에 접근합니다. 이런 방식으로 Comments 컴포넌트는 해당 포스트의 제목과 같은 정보를 활용할 수 있으며, 이는 댓글과 관련된 맥락을 제공하는 데 도움이 됩니다.
이러한 상황에서 useRouteLoaderData는 중첩된 라우트 간의 의존성과 상호작용을 관리하는 데 매우 유용합니다.
'Frontend > Development' 카테고리의 다른 글
javascript 이미지 색상 추출하기 (0) | 2024.08.11 |
---|---|
내부 요소 스크롤 위치 도달 시 부모 요소 스크롤 방지하기 (0) | 2024.05.28 |
FontFace를 활용하여 웹사이트의 글꼴을 동적으로 로딩하기 (0) | 2023.12.17 |
왜 컴포넌트 안에서 new QueryClient 사용을 지양해야 할까? (0) | 2023.11.24 |
React에서 한글 두 번 입력되는 오류, isComposing로 해결하기 (0) | 2023.10.29 |