次は、React でルーティングします。
参考サイトは「入門者でもわかるReact Routerを利用したルーティング設定の基礎」。
プロジェクト作成
yarn で my-routing-app というプロジェクトを作成します。
yarn create react-app my-routing-app
React Routerをインストールします。
cd ~/my-routing-app
yarn add react-router-dom
起動します。
cd ~/my-routing-app
yarn start
ルーティング
App.js を編集します。
~/my-routing-app/src/App.js
import { BrowserRouter, Route, Routes } from 'react-router-dom';
function App() {
return (
<BrowserRouter>
<h1>Hello React Router</h1>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</BrowserRouter>
);
}
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Contact() {
return <h2>Contact</h2>;
}
export default App;

今回の最終型
いきなりですが、参考サイトを元に作った今回の最終型です。
多くは、chatGPT さんにお願いしました。
App.js を変更します。
~/my-routing-app/src/App.js
import React from 'react';
import { BrowserRouter, Route, Routes, NavLink, Link, useMatch, useParams } from 'react-router-dom';
const posts = [
{ id: 1, title: 'React', content: 'React Tutorial' },
{ id: 2, title: 'Vue', content: 'Vue.js Tutorial' },
{ id: 3, title: 'Laravel', content: 'Laravel Tutorail' },
];
function App() {
return (
<BrowserRouter>
<header>
<h1>Hello React Router</h1>
<nav>
<ul>
<li>
<NavLinkWithActiveStyle to="/">
Home
</NavLinkWithActiveStyle>
</li>
<li>
<NavLinkWithActiveStyle to="/about">
About
</NavLinkWithActiveStyle>
</li>
<li>
<NavLinkWithActiveStyle to="/contact">
Contact
</NavLinkWithActiveStyle>
</li>
<li>
<NavLinkWithActiveStyle to="/posts">
Posts
</NavLinkWithActiveStyle>
</li>
</ul>
</nav>
</header>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
<Route path="/posts" element={<Posts />} />
<Route path="/posts/:id" element={<Post />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
);
}
function Home() {
return <h2>Home</h2>;
}
function About() {
return <h2>About</h2>;
}
function Contact() {
return <h2>Contact</h2>;
}
function Posts() {
return (
<div>
<h2>Post List</h2>
<ul>
{posts.map((post) => (
<li key={post.id}>
<NavLink to={`/posts/${post.id}`}>{post.title}</NavLink>
</li>
))}
</ul>
</div>
);
}
function Post() {
const { id } = useParams(); // useParams フックを使用して URL パラメータを取得
// id を数値に変換して投稿を検索
const post = posts.find((post) => post.id === Number(id));
// 投稿が見つからない場合は404エラーを表示
if (!post) {
return <NotFound />;
}
return (
<div>
<h2>{post.title}</h2>
<p>{post.content}</p>
</div>
);
}
function NotFound() {
return <h2>404 Not Found</h2>;
}
function NavLinkWithActiveStyle({ to, children }) {
const match = useMatch(to);
return (
<Link to={to} style={match ? { fontWeight: 'bold', color: 'red' } : {}}>
{children}
</Link>
);
}
export default App;

リンク先は別ファイルに
これまでは、すべて App.js に書いてきましたが、当然ながら別ファイルにするだろうと思って chatGPT に質問したところ、以下のような回答がありました。
ページごとに個別のコンポーネントを作成し、それらを App.jsx でルーティングするのが一般的です。
ですので、Home
、About
、Contact
などのページに対応する個別のコンポーネントファイルを作成し、それらを App.jsx
内でインポートしてルーティングすることが推奨されます。
当然でしょうね。
構造はこのようにしました。
src/
|-- components/
| |-- Home.jsx
| |-- About.jsx
| |-- Contact.jsx
| |-- Post.jsx
| |-- Posts.jsx
| |-- NavLinkWithActiveStyle.js
| └-- NotFound.jsx
└-- App.jsx
各ファイルの設定です。
~/my-routing-app/src/componets/Home.js
import React from 'react';
function Home() {
return (
<div>
<h2>Home Page</h2>
<p>Welcome to the Home Page!</p>
</div>
);
}
export default Home;
~/my-routing-app/src/componets/About.js
import React from 'react';
function About() {
return (
<div>
<h2>About Page</h2>
<p>This is About Page!</p>
</div>
);
}
export default About;
~/my-routing-app/src/componets/Contact.js
import React from 'react';
function Contact() {
return (
<div>
<h2>Contact Page</h2>
<p>Welcom. This is contact page.</p>
</div>
);
}
export default Contact;
~/my-routing-app/src/componets/Posts.js
import React from 'react';
import { NavLink } from 'react-router-dom'; // NavLink をインポート
function Posts() {
// 仮の投稿データ
const posts = [
{ id: 1, title: 'React', content: 'React Tutorial' },
{ id: 2, title: 'Vue', content: 'Vue.js Tutorial' },
{ id: 3, title: 'Laravel', content: 'Laravel Tutorail' },
];
return (
<div>
<h2>Post List</h2>
<ul>
{posts.map((post) => (
<li key={post.id}>
<NavLink to={`/posts/${post.id}`}>{post.title}</NavLink>
</li>
))}
</ul>
</div>
);
}
export default Posts;
~/my-routing-app/src/componets/Post.js
import React from 'react';
import { useParams } from 'react-router-dom'; // useParams をインポート
function Post() {
const { id } = useParams(); // useParams フックを使用して URL パラメータを取得
// 仮の投稿データ
const posts = [
{ id: 1, title: 'React', content: 'React Tutorial' },
{ id: 2, title: 'Vue', content: 'Vue.js Tutorial' },
{ id: 3, title: 'Laravel', content: 'Laravel Tutorail' },
];
// id を数値に変換して投稿を検索
const post = posts.find((post) => post.id === Number(id));
// 投稿が見つからない場合は404エラーを表示
if (!post) {
return <NotFound />;
}
return (
<div>
<h2>{post.title}</h2>
<p>{post.content}</p>
</div>
);
}
export default Post;
~/my-routing-app/src/componets/NavLinkWithActiveStyle.js
import React from 'react';
import { Link, useLocation } from 'react-router-dom';
function NavLinkWithActiveStyle({ to, children }) {
const location = useLocation();
const isActive = location.pathname === to;
return (
<Link
to={to}
style={isActive ? { fontWeight: 'bold', color: 'red' } : {}}
>
{children}
</Link>
);
}
export default NavLinkWithActiveStyle;
~/my-routing-app/src/componets/NotFound.js
import React from 'react';
function NotFound() {
return <h2>404 Not Found</h2>;
}
export default NotFound;
そうして、App.js の方でインポートします。
~/my-routing-app/src/App.js
import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Home from './components/Home';
import About from './components/About';
import Contact from './components/Contact';
import Posts from './components/Posts';
import Post from './components/Post';
import NotFound from './components/NotFound';
import NavLinkWithActiveStyle from './components/NavLinkWithActiveStyle';
function App() {
return (
<BrowserRouter>
<header>
<h1>Hello React Router</h1>
<nav>
<ul>
{/* NavLinkWithActiveStyle コンポーネントの使用 */}
<li>
<NavLinkWithActiveStyle to="/">Home</NavLinkWithActiveStyle>
</li>
<li>
<NavLinkWithActiveStyle to="/about">About</NavLinkWithActiveStyle>
</li>
<li>
<NavLinkWithActiveStyle to="/contact">Contact</NavLinkWithActiveStyle>
</li>
<li>
<NavLinkWithActiveStyle to="/posts">Posts</NavLinkWithActiveStyle>
</li>
</ul>
</nav>
</header>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
<Route path="/posts" element={<Posts />} />
<Route path="/posts/:id" element={<Post />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
);
}
export default App;
これはとてもわかりやすい。