오늘 몇 가지 고급 React Router 기술을 여러분과 공유하게 되어 정말 기쁩니다. React Router는 React 애플리케이션에서 동적이고 원활한 탐색을 생성할 수 있게 해주는 놀라운 도구입니다.
기본 라우팅 요구 사항에 일반적으로 사용되지만 라우팅 기능을 완전히 새로운 수준으로 향상시킬 수 있는 잘 알려지지 않은 몇 가지 기술이 있습니다.
오늘은 시간이 지나면서 발견한 제가 가장 좋아하는 몇 가지를 공유하겠습니다.
useNavigate
및 useLocation
후크 활용.
이 기사를 다 읽을 때쯤이면 이러한 고급 React Router 기술을 확실히 이해하고 이를 자신의 프로젝트에 적용할 자신감을 갖게 될 것입니다.
그럼 이제 함께 라우팅 기술을 강화해 봅시다!
준비 되었나요? 시작하자!
대규모 프로젝트를 수행할 때는 찾을 수 없는 경로를 관리하는 것이 필수적입니다. 서버에서 문서를 찾을 수 없을 때 HTTP 상태 코드 404를 반환하기 때문에 이러한 경로를 404 경로 라고 부르는 경우가 많습니다.
그런데, 당신이 고양이를 좋아한다면 http.cat 를 확인해 보는 것도 재미있을 것입니다.
이제 브라우저의 현재 URL과 일치하는 다른 경로가 없을 때마다 트리거되는 특수 경로를 만드는 방법을 살펴보겠습니다.
import {BrowserRouter, Routes, Route} from "react-router-dom"; function App() { return <BrowserRouter> <Routes> <Route path="/" element={<p>Landing page</p>}></Route> <Route path="/products" element={<p>Products page</p>}></Route> <Route path="*" element={<p>404 page</p>}></Route> </Routes> </BrowserRouter> }
기본 /
에 액세스하면 사용자는 랜딩 페이지로 이동됩니다. /products
페이지로 이동하면 제품 페이지로 연결됩니다. 그러나 특정 경로에 해당하지 않는 다른 링크에 접속하면 404 페이지가 표시됩니다.
이 동작의 이유는 path 속성이 *
로 설정된 404 페이지에 대한 특수한 <Route>
구현 때문입니다. 이 구성은 일치하는 다른 경로가 없을 때 React Router가 이 경로를 독점적으로 활용하도록 보장합니다. 404 경로의 구체적인 배치는 중요하지 않으며 <Routes>...</Routes>
섹션의 필수 구성 요소로 어디에든 위치할 수 있습니다.
앱이 실용적인 방식으로 경로를 활용할 수 있는 또 다른 방법은 메뉴에서 현재 활성화된 페이지를 강조 표시하는 것입니다.
홈 - 이 링크는 사용자를 기본 페이지로 이동합니다 /
정보 - 이 링크는 사용자를 정보 페이지 /about
으로 이동합니다.
React Router를 사용하면 사용자가 /about
경로에 있을 때 자동으로 About
링크를 강조 표시하는 것이 가능해졌습니다. 마찬가지로, 사용자가 /
경로에 있을 때 홈 링크를 강조 표시할 수 있습니다. 가장 좋은 점은 복잡한 조건이 필요 없이 이를 달성할 수 있다는 것입니다.
import {NavLink} from "react-router-dom"; function getClassName({isActive}) { if (isActive) { return "active"; // CSS class } } function App() { return <ul> <li> <NavLink to="/" className={getClassName}>Home</NavLink> </li> <li> <NavLink to="/about" className={getClassName}>About</NavLink> </li> </ul> }
위에 표시된 코드에는 active
클래스가 작동하려면 CSS가 필요합니다. 그래서 현재 활성화된 페이지의 메뉴 링크를 굵게 표시하고 눈에 띄게 만들어서 이를 향상시킬 수 있습니다.
.active { font-weight: bold; }
NavLink
요소의 className
속성은 문자열 대신 함수를 수용할 수 있는 유연성을 가지고 있습니다. 함수를 사용하기로 결정하면 객체가 매개변수로 제공되며 이 객체에는 이미 isActive
속성이 설정되어 있습니다. 함수 내에서 이 속성에 쉽게 액세스하기 위해 매개변수에 {isActive}
포함시켜 구조 분해를 사용합니다.
다음으로 isActive
진실한 값을 보유하고 있는지 확인합니다. 이 경우 CSS 클래스 이름 active
를 반환합니다.
React Router의 현재 경로가 NavLink
구성 요소의 to
속성과 일치하면 isActive
함수는 부울 값으로 평가됩니다.
결과적으로 React Router는 해당 <NavLink />
요소에 active
클래스를 원활하게 포함하여 현재 활성 경로임을 나타냅니다.
더 짧은 접근 방식을 선호하는 경우 삼항 연산자를 사용하여 위에서 언급한 코드를 리팩터링할 수 있습니다. 이 연산자는 condition ? truthy expression : falsy expression
형식을 사용하여 if/else 문을 바꾸는 방법을 제공합니다. condition ? truthy expression : falsy expression
.
저는 실제로 삼항 연산자를 많이 사용하지 않습니다. 왜냐하면 코드를 읽기 어렵게 만드는 경우가 많기 때문입니다. 그러나 이 경우에는 사용이 허용됩니다.
function getClassName({isActive}) { if (isActive) { return "active"; } else { return ""; } }
function getClassName({isActive}) { return isActive ? "active" : ""; }
단지 return 문이 삼항 연산자 외부에 위치하는지 확인하기만 하면 됩니다. isActive
조건이 true인 경우 ?
"active"
으로 실행됩니다. 그렇지 않으면 :
뒤의 표현식이 ""
실행됩니다.
이제 getClassName
이라는 별도의 함수 정의가 필요하지 않습니다. 대신 다음과 같은 화살표 함수를 사용할 수 있습니다. ({isActive}) => isActive ? "active" : ""
.
이 변경 사항을 읽기가 너무 어렵다면 이전과 같이 별도의 기능을 계속 사용할 수 있습니다.
import {NavLink} from "react-router-dom"; function App() { return <ul> <li> <NavLink to="/" className={({isActive}) => isActive ? "active" : ""}>Home</NavLink> </li> <li> <NavLink to="/about" className={({isActive}) => isActive ? "active" : ""}>About</NavLink> </li> </ul> }
오 이런, 난 당신의 생각을 거의 들을 수 있어요!
소진 씨, 당신은 DRY 원칙을 깨뜨린 거죠?
이것은 단지 예일 뿐입니다. 모든 것을 준비할 필요가 없습니다 😀
제가 평소 친구인 Link
대신 NavLink
사용하고 있다는 것을 이미 눈치채셨을 것입니다. 하지만 걱정하지 마세요. 이유를 설명해 드리겠습니다. 보시다시피 <Link />
구성 요소는 className
소품에 대한 함수 정의를 사용하는 것을 허용하지 않습니다. 네, 놀랍습니다. 하지만 <Link />
로 작업할 때는 그렇습니다.
내가 본 일반적인 실수 중 하나는 주니어 React 개발자가 <Link />
구성 요소의 className
prop에서 함수 정의를 사용하려고 시도했지만 단순히 작동하지 않는다는 것입니다.
관심이 있으시면 이 주제에 관한 기사를 쓸 수 있습니다. 댓글로 알려주세요!
특정 상황에서는 React 애플리케이션 내에서 프로그래밍 방식으로 페이지를 재배치해야 할 수도 있습니다. 예를 들어 방문자를 특정 페이지로 리디렉션하려면 요청을 제출하고 응답을 기다릴 수 있습니다.
/dashboard
로 리디렉션합니다.
이를 위해서는 프로그래밍 방식으로 사용자를 새 경로로 리디렉션하는 데 사용할 수 있는 함수를 반환하는 useNavigate()
후크를 사용해야 합니다.
구경하다:
import React, {useEffect} from "react"; import {useNavigate} from "react-router-dom"; function HelpPage() { const navigate = useNavigate(); useEffect(() => { const isLoggedIn = window.localStorage.getItem("isLoggedIn"); if (!isLoggedIn) { navigate("/login"); } }, []); return <h2>Help page</h2>; }
이 예에서는 localStorage에 isLoggedIn
키에 할당된 값이 있는지 확인합니다. 그렇지 않은 경우, navigate("/login")
함수를 사용하여 사용자를 /login
페이지로 리디렉션합니다.
작동하게 하려면 <BrowserRouter />
구성 요소 내에 중첩된 구성 요소 내에서 useNavigate()
후크를 사용하는 것을 기억하세요. 그렇지 않으면 제대로 작동하지 않습니다.
예를 들어 다음 예제는 작동하지 않습니다.
import React from "react"; import {BrowserRouter, useNavigate} from "react-router-dom"; function App() { // ❌ This breaks because the component was not wrapped by BrowserRouter, but its children are. const history = useNavigate(); return <BrowserRouter> {/* ... */} </BrowserRouter>; }
App()
구성 요소 내에서 useNavigate()
후크를 사용하려고 하면 약간의 문제가 발생할 수 있습니다. App()
컴포넌트를 <BrowserRouter />
로 래핑하지 않으면 작동하지 않기 때문입니다.
하지만 걱정하지 마세요!
좋은 소식은 App 내부의 모든 하위 구성 요소가 <BrowserRouter />
에 의해 자동으로 래핑되므로 문제 없이 해당 하위 구성 요소에서 useNavigate()
사용할 수 있다는 것입니다.
그러나 <App />
구성 요소 자체에서 useNavigate()
사용해야 하는 경우 간단한 해결책이 있습니다. <App />
래핑하는 상위 구성 요소를 생성하고 해당 상위 구성 요소 내에서 <BrowserRouter />
를 이동해야 합니다. 그렇게 하고 나면 준비가 완료되어 <App />
구성 요소의 useNavigate()
마음껏 사용할 수 있습니다 💗
웹사이트의 접근성을 높이려면 링크 구성 방식에 주의를 기울이는 것이 중요합니다. 이를 위해서는 다른 방법 대신 <Link />
요소를 사용하는 것이 좋습니다.
왜?
음, 이러한 요소는 자동으로 접근성 기능 으로 알려진 <a>
태그로 렌더링됩니다.
이제 친근한 팁이 있습니다. 일반 <Link />
요소를 useNavigate()
에서 제공하는 .push()
메서드로 바꾸지 마세요. 이 방법은 <Link />
요소를 사용할 수 없는 경우에만 사용해야 합니다.
일반적으로 fetch()
작업의 결과와 같은 특정 논리를 기반으로 프로그래밍 방식으로 사용자를 리디렉션해야 하는 경우입니다.
React Router가 새 주소로 이동할 때마다 코드 조각을 실행하고 싶다면 어떻게 해야 할까요?
useLocation
후크를 사용하면 쉽게 이를 수행할 수 있습니다. 하지만 세부 사항을 자세히 알아보기 전에 이것이 유용할 수 있는 몇 가지 시나리오를 살펴보겠습니다. 가장 일반적인 사용 사례 중 하나는 Google Analytics와 같은 분석 서비스에 페이지뷰 이벤트를 보내는 것입니다.
그러나 이제 Google Analytics 4가 이 작업을 자동으로 처리하므로 반드시 직접 구현할 필요는 없습니다.
그럼에도 불구하고 useLocation
후크에 대해 배우는 것은 다른 목적을 찾을 수 있으므로 여전히 가치가 있습니다. 예를 들어 이를 사용하여 다른 라이브러리 및 분석 서비스와 통합하거나 방문한 경로를 기반으로 특정 작업을 실행할 수 있습니다.
가능성은 무궁무진합니다!
useLocation
후크는 현재 사용 중인 경로에 대한 정보를 제공하므로 매우 편리합니다.
다음은 useLocation 후크를 사용하는 방법에 대한 친숙한 가이드입니다.
import {BrowserRouter, Routes, Route, useLocation} from "react-router-dom"; import {createRoot} from "react-dom/client"; function App() { const location = useLocation(); console.log(location.pathname); return <Routes> {/* routes here... */} </Routes> } createRoot(document.querySelector("#react-root")).render(<BrowserRouter><App /></BrowserRouter>);
이제 위치 변수를 통해 경로 정보에 접근할 수 있습니다. 현재 pathname
포함하는 개체입니다.
사용자가 현재 탐색 중인 경로를 확인하려면 location.pathname
사용하면 됩니다. /
, /about
또는 설정한 다른 경로와 같은 정보를 제공합니다.
useNavigate
후크와 마찬가지로 <BrowserRouter />
로 래핑된 구성 요소 내에서 코드를 실행하는 것이 중요합니다. 그렇지 않으면 useLocation
후크가 마법을 수행하지 않습니다.
위치가 변경되면 useLocation
후크를 사용하여 React Router의 현재 URL 경로에 액세스할 수 있습니다. useEffect
후크로 코드를 래핑하고 종속성을 location
으로 설정하면 새 URL로 이동할 때마다 특정 코드 부분을 실행할 수 있습니다.
import React, {useEffect} from "react"; import {BrowserRouter, Routes, Route, useLocation} from "react-router-dom"; import {createRoot} from "react-dom/client"; function App() { const location = useLocation(); // run a piece of code on location change useEffect(() => { console.log(location.pathname); // send it to analytic, or do some conditional logic here }, [location]); return <Routes> {/* routes here... */} </Routes> } createRoot(document.querySelector("#react-root")).render(<BrowserRouter><App /></BrowserRouter>);
사용자가 탐색 중에 새 경로로 이동할 때마다 useEffect
후크 내부의 코드가 실행되어 해당 작업을 수행합니다. 이는 기본적으로 위치 개체가 변경될 때마다 특정 코드가 실행되도록 하는 방법입니다.
마무리하기 위해 이 기사는 React Router에 대한 더 깊은 이해를 제공했습니다. 여기에 설명된 모든 기능을 사용하지 못할 수도 있습니다. 그래도 당신이 그것들을 알고 있다는 것은 환상적입니다. 나중에 유사한 기능을 통합해야 하는 경우, 어디를 살펴봐야 할지 정확히 알 수 있습니다. 따라서 쉽게 참조할 수 있도록 이 게시물을 저장하거나 북마크에 추가해 두시기 바랍니다. 질문이 있거나 추가 지원이 필요하면 언제든지 Twitter를 통해 저에게 연락해 주세요. 나는 도와주러 왔습니다!