🐎

react-router-dom v6環境下でのページ遷移

2022/06/02に公開

はじめに

  • react-router-dom v5 ▶︎ v6へのバージョンアップに伴い、コード記法が変更されたため、以下の動作確認を行う。  
      
      1.ネスト化されていないルート遷移
      2.ネスト化されたルート遷移
      3.各ページへ個別のテンプレート適用

動作環境

  • ライブラリバージョン
"dependencies": {
  "react": "18.0.0",
  "react-dom": "18.0.0",
  "react-router-dom": "6.3.0",
  "react-scripts": "4.0.3"
},

1.通常のルート遷移

/
/company
/contact
  • react-router-dom関連タグは<BrowserRouter>タグで囲う。
  • elementに遷移先ページのコンポーネントを指定する。
// App.tsx
import { BrowserRouter, Route, Routes, Link } from "react-router-dom";

import { Top } from "../src/components/pages/Top";
import { Company } from "../src/components/pages/Company";
import { Contact } from "../src/components/pages/Contact";
import "./styles.css";

export default function App() {
  return (
    <>
      <BrowserRouter>
        <div className="App">
          <Link to="/">to top</Link>
          <br />
          <Link to="/company">to company</Link>
          <br />
          <Link to="/contact">to contact</Link>

          <Routes>
            <Route path="/" element={<Top />} />
            <Route path="company" element={<Company />} />
            <Route path="contact" element={<Contact />} />
          </Routes>
        </div>
      </BrowserRouter>
    </>
  );
}

2.ネスト化されたルート遷移

/
/company
/company/info
/company/location
/contact
  • ネストするパスは親ルートの<Route>タグで囲む。
  • 親ルートである(<Company>)は、子ルート<CompanyInfo>を<Outlet>でレンダリングする。つまり、親ルートのコンポーネントで、<Outlet />を指定することで<CompanyInfo />がレンダリングされることになる。
// App.tsx
import { BrowserRouter, Route, Routes, Link } from "react-router-dom";

import { Top } from "../src/components/pages/Top";
import { Company } from "../src/components/pages/Company";
import { Contact } from "../src/components/pages/Contact";
import { CompanyInfo } from "../src/components/pages/CompanyInfo";
import { CompanyLocation } from "../src/components/pages/CompanyLocation";
import "./styles.css";

export default function App() {
  return (
    <>
      <BrowserRouter>
        <div className="App">
          <Link to="/">to top</Link>
          <br />
          <Link to="/company">to company</Link>
          <br />
          <Link to="/contact">to contact</Link>

          <Routes>
            <Route path="/" element={<Top />} />
            <Route path="company" element={<Company />}>
              <Route path="info" element={<CompanyInfo />} />
              <Route path="location" element={<CompanyLocation />} />
            </Route>
            <Route path="contact" element={<Contact />} />
          </Routes>
        </div>
      </BrowserRouter>
    </>
  );
}
// Company.tsx
import { Link, Outlet } from "react-router-dom";

export const Company = () => {
  return (
    <>
      <div>
        <h2>Company</h2>
        <nav>
	  // Outletには、CompanyInfoがレンダリングされる。
          <Link to="info">to company info</Link> |{" "}
	  // Outletには、CompanyLocationがレンダリングされる。
          <Link to="location">to company location</Link>
        </nav>
        <Outlet />
      </div>
    </>
  );
};
// CompanyInfo.tsx
export const CompanyInfo = () => {
  return (
    <>
      <div>
        <h2>CompanyInfo</h2>
      </div>
    </>
  );
};

3.各ページで個別のテンプレートを指定

  • /company配下とそれ以外で適用するテンプレートを分ける。
  • elementにテンプレートのコンポーネントを加えた形で、遷移先ページのコンポーネントを渡す。
    • <DefaultLayout>タグが適用された<Company>コンポーネント内で子要素の<Outlet>を呼び出す。子要素にも、親のテンプレートコンポーネントが適用される形となる。
<Routes>
  <Route path="/" element={<HeaderLayout><Top /></HeaderLayout>}/>
  <Route path="company" element={<DefaultLayout><Company /></DefaultLayout>}>
    <Route path="info" element={<CompanyInfo />} />
    <Route path="location" element={<CompanyLocation />} />
  </Route>
  <Route path="contact" element={<HeaderLayout><Contact /></HeaderLayout>} />
</Routes>
// DefaultLayout.tsx
import { Footer } from "../layout/Footer";

export const DefaultLayout = (props) => {
  const { children } = props;
  return (
    <>
      {children}
      <Footer />
    </>
  );
};

参考情報

https://github.com/hiroharu8864/check_nested_routes

Discussion