📌 React Router 라이브러리
- 프로덕션용으로 사용 가능한 싱글 페이지 앱을 구현(SPA)하기 위한 React Router 라이브러리
- URL이 변경돼도 싱글페이지로 렌더링 하는 기능을 지원
☑️ 검색엔진최적화(SEO) 설정
⏩ react-helmet-async 활용
: React 애플리케이션에서 동적으로 HTML <head>를 관리할 수 있게 해주는 라이브러리
- 리액트의 단점
➡︎ React는 하나의 index.html을 두고 있기 때문에 페이지 마다 페이지를 설명하는 메타태그를 설정하기 어렵다.
➡︎ SEO가 어렵다. - SEO(검색 엔진 최적화)와 소셜 미디어 공유를 위해 메타 태그, 타이틀, 링크 태그 등을 관리할 때 사용
- 기존의 react-helmet 라이브러리를 비동기적으로 사용할 수 있도록 개선한 버전
- 서버 사이드 렌더링(SSR)과 클라이언트 사이드 렌더링(CSR) 모두에서 사용할 수 있다.
설치
npm install react-helmet-async
1. HelmetProvider로 애플리케이션 또는 해당 컴포넌트를 감싼다.
- HelmetProvider를 사용하여 App.js를 감싼다.
import router from '@/router';
import { RouterProvider } from 'react-router-dom';
import { HelmetProvider } from 'react-helmet-async';
function App() {
return (
<HelmetProvider>
<RouterProvider router={router} />
</HelmetProvider>
);
}
export default App;
2. Helmet을 사용하여 HTML <head> 태그 내의 메타 데이터를 동적으로 설정한다.
- Helmet을 사용하여 페이지의 HTML <head>를 변경한다.
<title>, <meta/>, <link>, <style>, <script> 등을 관리한다.
(순서를 지켜야 한다.)
import { AppDivider, AppLink } from '@/components';
import Counter from '@/miniApp/Counter';
import TaskManager from '@/miniApp/TaskManager/TaskManager';
import { Helmet } from 'react-helmet-async';
function HomePage() {
return (
<>
<Helmet>
<title>앱 글로벌 상태 관리 with Zustand</title>
<meta
name="description"
content="Zustand를 사용하면 Context, useReducer, useState 없이 보다 효과적으로, 더 빠르게, 더 가볍게 상태를 관리할 수 있습니다."
/>
<meta property="og:title" content="이듬(E.UID) 블렌디드 러닝" />
<meta property="twitter:title" content="이듬(E.UID) 블렌디드 러닝" />
<meta property="og:type" content="site" />
<meta property="og:url" content="https://yamoo9.github.io/EUID" />
<meta
property="og:description"
content="Front-End 개발자를 꿈꾸는 이들을 위한 블렌디드 러닝으로 개발에 필요한 모든 것!"
/>
<meta
property="og:image"
content="https://yamoo9.github.io/EUID/og-image.jpg"
/>
<meta property="og:site:author" content="야무(yamoo9)" />
</Helmet>
<section id="page">
<div className="learn">
<h1>앱 글로벌 상태 관리 with Zustand</h1>
<p>
<AppLink
href="https://zustand.docs.pmnd.rs/getting-started/introduction"
isExternal
>
Zustand
</AppLink>{' '}
라이브러리를 사용해 앱 또는 컴포넌트의 상태를 효과적으로 관리하는
방법을 학습합니다.
</p>
<AppDivider />
<h2 lang="en" className="uppercase">
Counter
</h2>
<p>간단한 카운터 앱의 상태를 Zustand를 사용해 관리합니다.</p>
<Counter />
<AppDivider />
<h2 lang="en" className="uppercase">
Task Manager
</h2>
<p>
태스크 매니저 앱의 상태를 컨텍스트 + 리듀서 대신, Zustand를
사용하도록 변경해봅니다.
</p>
<TaskManager />
</div>
</section>
</>
);
}
export default HomePage;
⏩ Open Graph Protocols(OGP) 설정
: 웹 페이지가 소셜 미디어 플랫폼에서 어떻게 표시될지를 제어하는 메타데이터 표준
- 웹 페이지의 콘텐츠를 소셜 미디어에서 공유할 때 제목, 이미지, 설명 등을 미리보기 카드 형식으로 표시할 수 있다.
- 클릭률(CTR)을 높이고, 사용자 경험을 개선하며, 브랜드 인지도를 높이는 데 도움이 된다.
- 일반적인 HTML <meta> 태그를 사용한다.
- 속성
- og:title
: 공유되는 콘텐츠의 제목을 설정 - og:description
: 페이지에 대한 설명을 설정
➡︎ 이 설명은 소셜 미디어에서 링크를 공유할 때 미리보기 카드에 표시된다. - og:image
: 콘텐츠를 대표하는 이미지 URL을 설정
➡︎ 이 이미지는 소셜 미디어에서 링크를 공유할 때 미리보기 카드에 표시된다. - og:url
: 페이지의 URL을 설정
주로 정규화된 URL을 지정하는 데 사용된다. - og:type
: 콘텐츠의 유형을 설정
일반적인 웹 페이지는 website 또는 article을 사용한다. - og:site_name
: 사이트의 이름을 설정
➡︎ 페이지를 공유할 때 사이트 이름이 함께 표시된다. - og:locale
: 페이지의 언어 및 지역 설정을 지정 - og:video
: 페이지에 포함된 비디오의 URL을 지정 - og:audio
: 페이지에 포함된 오디오 파일의 URL을 지정
- og:title
<meta property="og:title" content="My Awesome Page">
<meta property="og:description" content="This is a description of my awesome page">
<meta property="og:image" content="https://www.example.com/image.jpg">
<meta property="og:url" content="https://www.example.com/my-page">
<meta property="og:type" content="website">
<meta property="og:site_name" content="My Awesome Website">
<meta property="og:locale" content="en_US">
<meta property="og:video" content="https://www.example.com/video.mp4">
<meta property="og:audio" content="https://www.example.com/audio.mp3">
☑️ 프로그래밍 방식 페이지 링크 설정
⏩ useNavigate()
: 컴포넌트 내에서 사용자를 다른 경로로 이동시키는 데 사용
- 이동 방식
- push
: 새로운 경로로 이동하며, 이전 페이지는 히스토리에 남아 있다.
- 뒤로 가기 버튼으로 이전 페이지로 돌아갈 수 있다⭕ - replace
: 새로운 경로로 이동하면서 현재 페이지를 히스토리에서 대체
- 뒤로 가기 버튼으로 돌아갈 수 없다❌
- push
- 상태 전달
: 경로 이동 시 상태(state)를 전달할 수 있고, 이를 통해 페이지 간 데이터 전달할 수 있다.
1. useNavigate() 훅 불러오기
import { useNavigate } from "react-router-dom";
2. useNavigate() 훅으로 navigate 함수 생성
- useNavigate()를 호출하면 경로를 변경할 수 있는 navigate 함수를 반환한다.
const navigate = useNavigate();
3. navigate 함수를 사용하여 페이지 이동
navigate('/path'); // 기본적으로 'push' 방식
navigate('/path', { replace: true }); // 'replace' 방식
예제) 클릭 시 파일 이동 컴포넌트
import React from 'react';
import { useNavigate } from 'react-router-dom';
const MyComponent = () => {
const navigate = useNavigate();
const handleClick = () => {
navigate('/about', { state: { fromHome: true } });
};
return (
<div>
<h1>Home Page</h1>
<button onClick={handleClick}>Go to About Page</button>
</div>
);
};
export default MyComponent;
☑️ 네비게이션 상태 확인
⏩ useNavigation() 훅
: 현재의 네비게이션 상태와 관련된 정보를 가져오는 데 사용
- 특징
- 네비게이션 상태 추적: 현재 네비게이션이 진행 중인지, 완료되었는지, 오류가 발생했는지 등의 상태를 알 수 있다.
- 폼 데이터 처리: 폼 제출로 인해 발생한 네비게이션에서 제출된 데이터에 접근할 수 있다.
- 네비게이션 응답 처리: 네비게이션 응답의 JSON 데이터나 텍스트 데이터를 처리할 수 있다.
- React Router 6.4 이상에서 사용할 수 있다.
1. 불러오기
import { useNavigation } from "react-router-dom";
2. useNavigation 훅 호출
- useNavigation 훅을 호출하여 네비게이션 상태를 가져온다.
- 반환된 객체를 사용하여 현재 네비게이션 상태를 확인하고, 조건부 렌더링을 통해 UI를 업데이트할 수 있다.
const navigation = useNavigation();
3. 속성 사용
- navigation.state
: 현재 네비게이션 상태
값: 'idle', 'loading', 'error' - navigation.location
: 현재의 location 객체를 포함한다.
➡︎ URL 경로, 검색 쿼리, 해시 등을 포함한다.
형식: { pathname: string, search: string, hash: string, state: any } - navigation.formData
: 폼 제출로 인해 네비게이션이 발생한 경우, 제출된 폼의 데이터를 포함한다.
형식: FormData 객체 - navigation.json
: 네비게이션 응답이 JSON 데이터를 포함할 때 사용
➡︎ JSON API와 상호작용할 때 유용하다.
형식: Promise<any> - navigation.text
: 네비게이션 응답이 텍스트 데이터를 포함할 때 사용됩니다.
형식: Promise<string> - navigation.formAction
: 현재 폼 제출의 액션 URL을 나타낸다.
형식: string - navigation.formMethod
: 현재 폼 제출의 메서드(POST, GET 등)를 나타낸다.
형식: string
function SomeComponent() {
const navigation = useNavigation();
navigation.state;
navigation.location;
navigation.formData;
navigation.json;
navigation.text;
navigation.formAction;
navigation.formMethod;
navigation.formEncType;
}
예제) 현재 네비게이션 상태를 추적, 이 상태를 기반으로 UI를 동적으로 업데이트
import { Outlet, useNavigation } from 'react-router-dom';
import { AppFooter, AppHeader, AppNav, AppSpinner } from '@/components';
function RootLayout() {
const navigation = useNavigation();
const isLoading = navigation.state === 'loading';
return (
<div className="h-screen bg-indigo-50/30 flex flex-col">
<AppHeader />
<AppNav />
<main className="flex-1 m-4">
{isLoading ? (
<AppSpinner
size={100}
className="fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"
/>
) : (
<Outlet />
)}
</main>
<AppFooter />
</div>
);
}
export default RootLayout;
☑️ 다이내믹 세그먼트(Dynamic Segment) 설정
: URL 경로의 일부를 동적으로 받아와 라우트를 매칭하는 방법
- 주로 특정 리소스의 ID나 이름 등을 URL에 포함시켜 해당 리소스에 접근할 때 사용된다.
- 라우트 정의 시 URL 경로에서 콜론(:)을 사용하여 다이내믹 세그먼트를 설정한다.
이를 통해 다양한 리소스나 데이터를 동적으로 처리하는 애플리케이션을 쉽게 구현할 수 있다.
⏩ useParams()
: 현재 URL의 동적 세그먼트(Dynamic Segment)에 전달된 파라미터 값을 가져오는 데 사용
- 이 훅을 사용하면 라우트 경로에 포함된 변수를 쉽게 접근하여 컴포넌트 내에서 활용할 수 있다.
- 특징
- URL 파라미터 접근
: useParams()는 현재 URL에 매칭된 라우트의 파라미터 값을 객체 형태로 반환한다. - 동적 경로 처리
: URL 경로에서 `:id`와 같은 동적 세그먼트를 정의하고, 해당 경로에 접근할 때 전달된 값을 읽어올 수 있다.
- URL 파라미터 접근
- 사용 예시
- 상세 페이지
: 특정 리소스(ex. 특정 ID를 가진 블로그 글, 제품, 사용자 등)의 상세 페이지를 구현할 때,
useParams()를 사용해 URL에서 해당 리소스의 ID를 가져와 필요한 데이터를 로드하고 표시한다. - 편집 페이지
: 사용자가 특정 리소스를 편집할 수 있는 페이지를 만들 때, URL에서 리소스의 ID를 가져와 그 데이터를 불러오고 수정할 수 있게 한다. - 필터링 및 정렬된 리스트
: URL에 필터 조건(ex. 카테고리, 태그)을 포함하여 해당 조건에 맞는 데이터를 필터링하거나 정렬된 리스트를 보여줄 때 사용한다.
- 상세 페이지
1. 라우트 설정에서 다이내믹 세그먼트 정의
- 라우트 설정에서 다이내믹 세그먼트를 정의한다.
다이내믹 세그먼트 👉 URL 경로에서 콜론(:)으로 시작하는 부분
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import UserDetail from './components/UserDetail';
const router = createBrowserRouter([
{
path: '/users/:id', // :id(다이내믹 세그먼트) 설정
element: <UserDetail />, // 해당 경로에 접근 시 UserDetail 컴포넌트 렌더링
},
]);
function App() {
return <RouterProvider router={router} />;
}
export default App;
2. useParams()로 파라미터 값 가져오기
- 다이내믹 세그먼트로 전달된 파라미터 값을 가져오려면,
해당 라우트로 렌더링되는 컴포넌트에서 useParams() 훅을 사용한다. - ID를 기반으로 데이터를 가져오거나 렌더링할 수 있다.
import { useParams } from 'react-router-dom';
function UserDetail() {
const { id } = useParams(); // URL의 :id 값에 접근
return (
<div>
<h1>User Detail</h1>
{/* 가져온 id 값을 표시 */}
{/* ID를 기반으로 데이터를 가져오거나 렌더링할 수 있음 */}
<p>User ID: {id}</p>
</div>
);
}
export default UserDetail;
⏩ useSearchParams() 훅
: URL의 쿼리 파라미터(query parameters)에 접근하여 읽고 수정할 수 있게 해준다.
- 쿼리 파라미터(query parameters) : URL의 ? 뒤에 오는 키-값 쌍
- 페이지의 상태를 관리하거나 데이터를 필터링할 때 유용하다.
- useSearchParams() 훅은 두 가지 값을 반환한다.
- searchParams: URLSearchParams 객체, 현재 URL의 쿼리 파라미터를 관리
- setSearchParams: 쿼리 파라미터를 수정할 수 있는 함수
- 특징
- 쿼리 파라미터 접근
: URL의 쿼리 문자열을 읽어서 현재 상태를 컴포넌트에서 쉽게 사용할 수 있다. - 쿼리 파라미터 수정
: 쿼리 파라미터를 업데이트하여 URL을 변경할 수 있고, 페이지의 상태를 동적으로 조절할 수 있다.
- 쿼리 파라미터 접근
- 사용 예시
- 검색 기능
: 사용자가 입력한 검색어를 쿼리 파라미터로 전달하여 검색 결과를 필터링한다. - 필터링 및 정렬
: URL 쿼리 파라미터를 사용하여 리스트를 필터링하거나 정렬 기준을 지정한다. - 페이지 상태 유지
: 페이지 이동 시 상태를 유지하고자 할 때, 페이지 네비게이션 시 현재 페이지 번호를 쿼리 파라미터로 관리한다.
- 검색 기능
- 속성
- get(name): 쿼리 파라미터의 값을 가져온다.
- getAll(name): 모든 값을 배열로 가져온다.
- has(name): 쿼리 파라미터의 존재 여부를 확인한다.
- set(name, value): 값을 설정하거나 업데이트한다.
- append(name, value): 값을 추가한다.
- delete(name): 쿼리 파라미터를 삭제한다.
- toString(): 쿼리 문자열을 반환한다.
- entries(), keys(), values(): 각각 키-값 쌍, 키, 값을 반복 가능한 객체로 반환한다.
1. 불러오기
import { useSearchParams } from 'react-router-dom';
2. useSearchParams() 호출 후 배열로 받기
const [searchParams] = useSearchParams();
3. 현재 'query' 값 가져오기
const query = searchParams.get('query');
예제 1) 쿼리 파라미터 읽기
import React from 'react';
import { useSearchParams } from 'react-router-dom';
function SearchPage() {
const [searchParams] = useSearchParams(); // 현재 URL의 쿼리 파라미터를 가져옵니다
const query = searchParams.get('query'); // 'query' 파라미터의 값을 가져옵니다
return (
<div>
<h1>Search Page</h1>
<p>Current query: {query || 'No query specified'}</p>
</div>
);
}
export default SearchPage;
예제 2) 쿼리 파라미터 수정하기
import React from 'react';
import { useSearchParams } from 'react-router-dom';
function SearchPage() {
const [searchParams, setSearchParams] = useSearchParams(); // 현재 쿼리 파라미터를 가져오고 업데이트하는 함수
const query = searchParams.get('query') || '';
const handleSearchChange = (event) => {
const newQuery = event.target.value;
setSearchParams({ query: newQuery }); // 쿼리 파라미터를 업데이트합니다
};
return (
<div>
<h1>Search Page</h1>
<input
type="text"
value={query}
onChange={handleSearchChange}
placeholder="Enter search query"
/>
<p>Current query: {query}</p>
</div>
);
}
export default SearchPage;
GitHub - staylor/react-helmet-async: Thread-safe Helmet for React 16+ and friends
Thread-safe Helmet for React 16+ and friends. Contribute to staylor/react-helmet-async development by creating an account on GitHub.
github.com
[React] SEO를 위한 react-helmet-async, react-snap
SEO를 위한 react-helmet-async, react-snap
velog.io
React Router | Notion
클라이언트 사이드 라우팅(CSR) 라이브러리
euid.notion.site