[React] 그 외 리액트 라우터 부가 기능들

겨레·2024년 12월 4일

[React] 리액트 스터디

목록 보기
76/95

해당 시리즈 이전 포스팅에 작성한 기능 외에도 리액트 라우터 부가 기능들이 더 있다. 책에 있는 것들로 확인해보고자 한다!

  • withRouter
  • Switch
  • NavLink

요 세 녀석들인데... 불안하다!!!
왠지 요 녀석들도 뭔가 사라졌거나 달라졌을 것 같다.

역시나 React Router v6에서 중요한 변화가 있었다고 한다.
확인해보도록 하자...


① withRouter (⇒ React Router v6에서 withRouter 삭제됨)

이전에는 withRouter를 사용해서 Route 컴포넌트가 전달하는 history, location, match와 같은 props를 하위 컴포넌트에 전달할 수 있었다.

✅ v6에서는 useNavigate, useLocation, useParams, useMatch 등의 훅을 사용해 직접 접근하도록 변경해야 한다.
✅ 이렇게 훅을 사용하면 함수형 컴포넌트에서 history, location, match 등을 직접 받아서 사용할 수 있다.

  • 예제
// v5에서의 예
import { withRouter } from 'react-router-dom';

const MyComponent = ({ history, location, match }) => {
  // history, location, match 사용
};

// v6에서의 예
import { useNavigate, useLocation } from 'react-router-dom';

const MyComponent = () => {
  const navigate = useNavigate();
  const location = useLocation();
  
  // navigate, location 사용
};

  • WithRouterSample.jsx
import React from "react";
import { useLocation, useNavigate, useParams } from "react-router-dom"; // 훅 임포트
const WithRouterSample = () => {
  const location = useLocation(); // location 훅
  const navigate = useNavigate(); // navigate 훅
  const params = useParams(); // URL params

  return (
    <div>
      <h4>Location</h4>
      <textarea
        value={JSON.stringify(location, null, 2)}
        rows={7}
        readOnly={true}
      />
      <h4>Params (Match)</h4>
      <textarea
        value={JSON.stringify(params, null, 2)}
        rows={7}
        readOnly={true}
      />
      <button onClick={() => navigate("/")}>홈으로</button>
    </div>
  );
};

export default WithRouterSample;

왜 나는 match 저렇게 나오지 ㅠㅠ


② Switch (⇒ React Router v6에서 Routes로 변경됨)

Switch는 이전 버전에서 첫 번째로 매칭되는 경로에 맞는 컴포넌트를 렌더링하는 역할을 했다.

✅ v6에서는 Routes로 대체됐다. 모든 Route는 경로 순서대로 평가되며, element prop을 사용하여 컴포넌트를 전달한다.
✅ Route 컴포넌트는 이제 element prop을 사용해 렌더링할 컴포넌트를 지정하고, render나 children은 제거됐다.

  • 예제
// v5에서의 예
// v5에서 Switch와 Route 사용
import React from "react";
import { Switch, Route, withRouter } from "react-router-dom";

const Home = () => <div>Home</div>;
const About = () => <div>About</div>;

const App = () => (
  <Switch>
    <Route exact path="/" component={Home} />
    <Route path="/about" component={About} />
  </Switch>
);

// withRouter를 사용하여 history, location, match 접근
const MyComponent = ({ history, location, match }) => {
  console.log(history, location, match); // v5에서 접근 가능
  return <div>My Component</div>;
};

export default withRouter(MyComponent);


// v6에서의 예
// v6에서 Routes와 Route 사용
import React from "react";
import { Routes, Route, useNavigate, useLocation } from "react-router-dom";

const Home = () => <div>Home</div>;
const About = () => <div>About</div>;

const App = () => (
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/about" element={<About />} />
  </Routes>
);

// useNavigate와 useLocation을 사용하여 history, location 대체
const MyComponent = () => {
  const navigate = useNavigate(); // navigate로 탐색
  const location = useLocation(); // location 정보를 가져옴

  console.log(location); // location 객체 출력

  return (
    <div>
      <button onClick={() => navigate("/about")}>Go to About</button>
    </div>
  );
};

export default MyComponent;


✅ NavLink는 여전히 활성화된 링크를 스타일링하는데 사용된다.
✅ 기본적으로 activeClassName 대신 className이나 style을 이용해 활성화된 상태를 스타일링할 수 있다.
✅ activeClassName은 제거되었고, 대신 className에 함수 형태로 스타일을 적용할 수 있다.

  • 예시
// v5에서의 예
import { NavLink } from 'react-router-dom';

const App = () => (
  <NavLink to="/home" activeClassName="active-link">
    Home
  </NavLink>
);

// v6에서의 예
import { NavLink } from 'react-router-dom';

const App = () => (
  <NavLink 
    to="/home" 
    className={({ isActive }) => (isActive ? 'active-link' : '')}
  >
    Home
  </NavLink>
);

// v6에서의 예2
import React from "react";
import { NavLink } from "react-router-dom";
import "./App.css"; // 스타일 파일을 별도로 관리

const App = () => (
  <nav>
    <NavLink
      to="/home"
      className={({ isActive }) => (isActive ? "active-link" : "inactive-link")}
      style={({ isActive }) =>
        isActive
          ? {
              color: "white",
              backgroundColor: "blue",
              padding: "10px 20px",
              borderRadius: "5px",
            }
          : {
              color: "blue",
              textDecoration: "none",
            }
      }
    >
      Home
    </NavLink>
    <NavLink
      to="/about"
      className={({ isActive }) => (isActive ? "active-link" : "inactive-link")}
      style={({ isActive }) =>
        isActive
          ? {
              color: "white",
              backgroundColor: "green",
              padding: "10px 20px",
              borderRadius: "5px",
            }
          : {
              color: "green",
              textDecoration: "none",
            }
      }
    >
      About

profile
호떡 신문지에서 개발자로 환생

0개의 댓글