리액트 라우터에 대해 공부를 하다 보니 loader에 대해 배우는데 상태관리의 영역과 겹치는 부분이 있다고 느껴져 조사를 해봤습니다. 제가 생각하기에는 페이지에 접근할 때 초기 데이터 패칭 인터페이스나, 비동기로 데이터를 연동해서 연결해주는 부분, 그리고 컴포넌트 단에서 불러온 데이터를 객체에 연결하여 사용하는 부분 등이 비슷하게 느껴졌습니다. 아래 예시처럼요.
리액트 라우터의 loader
를 사용하는 컴포넌트 예시
import { createBrowserRouter, RouterProvider, Route, useLoaderData } from "react-router-dom";
const postLoader = async ({ params }) => {
const response = await fetch(`https://example.com/posts/${params.postId}`);
const post = await response.json();
return post; // 반환된 post는 라우트 컴포넌트에서 사용할 수 있음
};
const Post = () => {
const post = useLoaderData(); // loader에서 반환된 데이터를 사용
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
);
};
const router = createBrowserRouter([
{
path: "/post/:postId",
element: <Post />,
loader: postLoader, // loader 함수를 라우트에 연결
},
]);
function App() {
return <RouterProvider router={router} />;
}
Redux를 사용하는 컴포넌트 예시
import { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { fetchData } from "./store/actions";
function PostContainer({ postId }) {
const dispatch = useDispatch();
const post = useSelector((state) => state.post.data);
const isLoading = useSelector((state) => state.post.isLoading);
useEffect(() => {
dispatch(fetchData(postId));
}, [dispatch, postId]);
if (isLoading) {
return <div>Loading...</div>;
}
return (
<div>
<h1>{post.title}</h1>
<p>{post.content}</p>
</div>
);
}
리액트 라우터의 loader
- 리액트 라우터에서는
loader
를 사용해 특정 라우트에 진입하기 전에 필요한 데이터를 미리 로딩할 수 있습니다. 이는 사용자에게 라우트 관련 데이터를 렌더링하기 전에 미리 준비하고자 할 때 유용합니다.
리덕스 상태 관리 라이브러리
- 리덕스는 애플리케이션의 상태를 관리하는 데 초점을 맞춘 상태 관리 라이브러리입니다. 이는 애플리케이션의 다양한 컴포넌트 간의 상태 공유, 상태 업데이트의 예측 가능성, 디버깅 용이성 등을 목적으로 합니다.
두 기술의 공통점
데이터 패칭의 자동화: 둘 다 애플리케이션에서 필요한 데이터를 자동으로 패칭하는 메커니즘을 제공합니다. 이를 통해 데이터를 효율적으로 로드하고 관리할 수 있습니다.
비동기 작업 처리: 리액트 라우터의
loader
와 리덕스 모두 비동기 API 호출(예: HTTP 요청)을 처리할 수 있는 기능을 포함하고 있습니다. 이를 통해 백엔드 시스템과의 비동기 통신을 쉽게 구현할 수 있습니다.사용자 경험 개선: 두 방식 모두 애플리케이션의 사용자 경험을 개선하는 데 도움이 됩니다. 데이터 패칭 로직을 적절히 관리함으로써, 사용자는 필요한 데이터가 준비될 때까지 기다리는 시간을 줄일 수 있습니다.
두 기술의 차이점
목적의 차이: 리액트 라우터의
loader
는 라우팅과 관련된 데이터 로딩 및 사용자 입력 처리에 특화되어 있는 반면, 리덕스는 애플리케이션 전반의 상태 관리에 더 초점을 맞추고 있습니다.loader
케이스: 사용자가 온라인 쇼핑몰에서 상품 상세 페이지로 이동하는 경우사용자가 상품 목록에서 특정 상품을 클릭할 때, 해당 상품의 상세 정보 페이지로 라우팅됩니다.
loader
를 사용하면 이동 전에 상품의 상세 정보를 서버로부터 미리 로드하여, 페이지가 렌더링되는 즉시 정보를 표시할 수 있습니다.리덕스 케이스: 사용자가 다양한 컴포넌트에서 접근 가능한 프로필 정보를 업데이트하는 경우
사용자가 설정 페이지에서 자신의 프로필 정보를 업데이트하면, 이 정보는 애플리케이션의 여러 부분(예: 헤더의 사용자 이름 표시, 댓글 작성자 정보 등)에 반영되어야 합니다. 리덕스를 사용하여 프로필 정보를 중앙 스토어에 저장하고 관리하면, 정보의 업데이트가 전체 애플리케이션에 일관되게 반영됩니다.
사용 사례의 차이: 리액트 라우터의
loader
는 페이지 전환 시 데이터를 준비하거나, 특정 라우트에서 발생하는 이벤트를 처리하는데 주로 사용되는 반면, 리덕스는 애플리케이션의 다양한 부분에서 발생하는 상태 변화를 중앙에서 관리하고자 할 때 사용됩니다.loader
케이스: 블로그 포스트 목록에서 사용자가 특정 포스트를 선택하여 상세 페이지로 이동하는 경우사용자의 이동에 따라 해당 포스트의 내용을 미리 로드하여 상세 페이지의 로딩 시간을 최소화합니다. 이 방식은 사용자가 콘텐츠를 빠르게 볼 수 있도록 하여 사용자 경험을 개선합니다.
리덕스 케이스: 소셜 미디어 애플리케이션에서 사용자의 게시물 목록 관리
사용자가 게시물을 작성, 수정, 삭제할 때마다 이러한 상태 변화는 애플리케이션의 여러 부분(예: 메인 피드, 사용자 프로필 페이지, 최근 활동)에 반영되어야 합니다. 리덕스를 사용하면 이러한 상태 변화를 중앙에서 관리하고, 애플리케이션의 다른 부분과 일관성 있게 데이터를 동기화할 수 있습니다.
기능적 차이: 리액트 라우터의
loader
는 라우팅과 직접적으로 연관된 작업에 특화되어 있어서, 페이지 전환 시 필요한 데이터 로딩이나 폼 제출 같은 작업을 쉽게 처리할 수 있게 해줍니다. 반면, 리덕스는 애플리케이션의 상태 변화를 효율적으로 관리하고, 이를 컴포넌트에 연결해주는 데 집중 되어 있습니다.loader
케이스: 실시간 뉴스 피드 애플리케이션에서 카테고리별 뉴스 페이지로 이동하는 경우각 뉴스 카테고리 페이지로 이동할 때, 해당 카테고리의 최신 뉴스 목록을 미리 로드합니다. 이는 페이지 라우팅과 직접 연결된 데이터 로딩에 특화된 접근 방식입니다.
리덕스 케이스: 전자상거래 애플리케이션에서 사용자의 장바구니 상태 관리
설명: 사용자가 상품을 장바구니에 추가하거나 삭제할 때, 이러한 상태 변화는 애플리케이션의 장바구니 아이콘, 결제 페이지 등 여러 부분에 일관되게 반영되어야 합니다. 리덕스를 사용하면 이러한 전역 상태를 효율적으로 관리하고, 애플리케이션 전반에 걸쳐 상태 변화를 동기화할 수 있습니다.
마치며
리액트 라우터의 loader
와 리덕스는 각각 라우팅 시 데이터 준비와 애플리케이션 전반의 상태 관리에 특화된 해결책을 제공합니다. 이들 기술의 공통점과 차이점을 이해하는 것은 개발자가 애플리케이션의 구조와 요구사항에 적합한 선택을 하는 데 도움이 됩니다. 따라서, 리액트 라우터의 loader
와 리덕스를 상호 배타적인 옵션이 아니라, 각각의 강점을 활용하여 조화롭게 사용하는 구조를 고민해야 된 다는 점을 알 수 있었습니다.