
Section 21(3)
TIL1) useRouteLoaderData 훅 및 다른 라우트에서 데이터 액세스하기
예전에, 훅 이름이 엄청 긴게 있었다. 그때, 들은 얘기 중 재밌었던 건, 이렇게 길면 잘 안쓰는것이다.ㅋㅋㅋㅋ
근데, 그냥 여기서 다시 정리해보면!
useRouteLoaderData는 React Router에서 제공하는 훅으로, 특정 라우트에서 로드된 데이터를 가져오기 위해 사용된다. (말 그대로 풀어논 느낌)
이 훅은 라우트 레벨에서 데이터 로딩을 처리하며, 리액트 컴포넌트에서 데이터를 쉽게 접근할 수 있게 도와준다.
라우트 설정에서 loader 속성으로 데이터를 가져오는 함수를 정의하면, 해당 데이터는 해당 라우트 컴포넌트에서 useRouteLoaderData 훅을 통해 액세스
한다
import { useRouteLoaderData } from 'react-router-dom';
function ProductDetail() {
const productData = useRouteLoaderData('product-detail'); // 라우트 ID를 기반으로 데이터 불러옴
return (
<div>
<h1>{productData.name}</h1>
<p>{productData.description}</p>
<p>Price: ${productData.price}</p>
</div>
);
}
export default ProductDetail;
request()메서드로 액션 재사용하기
React Router는 액션(action)을 통해 사용자가 특정 라우트에서 발생시키는 이벤트를 처리한다. request() 메서드는 라우트 내에서 데이터를 전송하고, 이를 서버와 상호작용할 수 있도록 돕는다. 이를 활용해 액션을 재사용하면 여러 라우트에서 동일한 액션 처리 로직을 공유한다.
export async function action({ request }) {
const formData = await request.formData(); // request 메서드를 통해 FormData를 처리
const data = {
name: formData.get('name'),
email: formData.get('email')
};
// 서버로 전송하거나 비즈니스 로직 처리
await fetch('/api/submit', {
method: 'POST',
body: JSON.stringify(data),
headers: { 'Content-Type': 'application/json' }
});
return null; // 페이지 리로드 등 추가 처리
}
여기서 request() 메서드는 사용자가 제출한 폼 데이터를 받아 서버로 전송하거나 필요한 비즈니스 로직을 처리하는 데 사용된다. 이를 통해 다른 라우트에서도 동일한 액션을 재사용할 수 있다.
defer() 함수로 데이터 가져오기
defer() 함수는 React Router에서 비동기 데이터를 로드할 때 사용된다. 페이지가 로드되기 전까지 일부 데이터는 바로 가져오고, 나머지는 비동기로 가져오는 방식으로 최적화를 할 수 있다. 이 기능은 특히 큰 데이터를 효율적으로 처리할 때 유용하다.
import { defer } from 'react-router-dom';
export function loader() {
const productData = fetch('/api/products'); // 비동기 요청
return defer({
products: productData, // 비동기 데이터를 defer로 감싸서 전달
});
}
defer()는 일부 데이터를 즉시 반환하지 않고 비동기적으로 처리하게 만든다. 컴포넌트는 해당 데이터를 기다리는 동안 UI를 보여주거나 다른 작업을 처리할 수 있다.
useLoaderData와 함께 사용
import { useLoaderData } from 'react-router-dom';
function ProductList() {
const data = useLoaderData(); // loader에서 반환된 데이터를 가져옴
return (
<div>
<h1>Product List</h1>
{data.products && (
<ul>
{data.products.map(product => (
<li key={product.id}>{product.name}</li>
))}
</ul>
)}
</div>
);
}
질문거리
request() 메서드를 사용할 때 POST 요청 외에 다른 HTTP 메서드(GET, PUT, DELETE 등)를 활용할 수 있는 방법은?
하나의 액션에서 여러 유형의 폼 데이터를 처리해야 할 경우, 데이터 구조나 액션 로직은 어떻게 설계하면 좋을까?
라우트 내에서 request()와 defer()를 적절하게 조합해 사용하는 사례는 어떤 것이 있을까?
defer() 함수로 데이터 일부를 미리 로드하고, 나머지를 비동기적으로 처리할 때 데이터의 일관성을 유지하는 좋은 방법은?
defer()와 useEffect()를 함께 사용하는 것이 좋을 때와 그렇지 않은 상황은 어떤 차이가 있을까?