Memo

メモ > 技術 > フレームワーク: React.js > React Router

React Router
2022年中にreact-router-domの理解を深めたい #React - Qiita https://qiita.com/TMDM/items/0939ff52ab5b459303d7 React Router でルーティングを管理しよう(初心者向け) | Muscle Coding https://musclecoding.com/react-router/ React Routerのルーティング実装 https://zenn.dev/takaya39/articles/4669c3fd1c7f04 ■準備 今回は「プロジェクトを作成して開発」で作成したプロジェクトを使用する。 >cd C:\path\to\react_app >npm install react-router-dom >npm start src/App.js の内容を以下のようにし、ページにアクセスして「react-router」と表示されることを確認する。
function App() { return ( <div> <h1>react-router</h1> </div> ); } export default App;
■ルーティングの確認 以下のファイルを作成する。 src/routes/Home.js
import { Link } from "react-router-dom"; export const Home = () =>{ return ( <div> <p>Home</p> <ul> <li><Link to="/about">About</Link></li> <li><Link to="/contact">Contact</Link></li> </ul> </div> ) }
src/routes/About.js
import { Link } from "react-router-dom"; export const About = () =>{ return ( <div> <p>About</p> <ul> <li><Link to="/">Home</Link></li> </ul> </div> ) }
src/routes/Contact.js
import { Link } from "react-router-dom"; export const Contact = () =>{ return ( <div> <p>Contact</p> <ul> <li><Link to="/">Home</Link></li> </ul> </div> ) }
src/routes/Notfound.js
import { Link } from "react-router-dom"; export const Notfound = () =>{ return ( <div> <p>Notfound</p> <ul> <li><Link to="/">Home</Link></li> </ul> </div> ) }
以下のファイルを編集する。 src/App.js
import { Routes, Route } from "react-router-dom"; import { Home } from "./routes/Home"; import { About } from "./routes/About"; import { Contact } from "./routes/Contact"; import { Notfound } from "./routes/Notfound"; function App () { return ( <div> <h1>react-router</h1> <Routes> <Route path="/" element={ <Home /> } /> <Route path="/about" element={ <About /> } /> <Route path="/contact" element={ <Contact /> } /> <Route path="*" element={ <Notfound /> } /> </Routes> </div> ); } export default App;
src/index.js
import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import { BrowserRouter } from 'react-router-dom'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <BrowserRouter> <App /> </BrowserRouter> ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals();
これで http://localhost:3000/ にアクセスすると、Homeの画面が表示される。 各リンクからAboutやContactに遷移でき、URLも変化する。 存在しないURLにアクセスされた場合、Notfoundの画面が表示される。 ■データの取得 以下が参考になるか。 React Router v6のルーティング方法を解説 - createBrowserRouterとData APIsの活用法 | DevelopersIO https://dev.classmethod.jp/articles/react-router-v6-4-createbrowserrouter-data-apis/ 以下は参考記事のメモ。 Laravel x Inertia.js 現代のモノリス によるお手軽 SPA 開発 - Speaker Deck https://speakerdeck.com/tutida/laravel-x-inertia-dot-js-xian-dai-nomonorisu-niyoruoshou-qing-spa-kai... 以下はChatGPTによるコード。 src/routes/Home.js
import React, { useEffect, useState } from "react"; import { Link } from "react-router-dom"; export const Home = () => { const [posts, setPosts] = useState([]); const [error, setError] = useState(null); // 外部データを取得するための useEffect フック useEffect(() => { const fetchPosts = async () => { try { const response = await fetch("https://jsonplaceholder.typicode.com/posts?_limit=5"); if (!response.ok) { throw new Error(`Error: ${response.statusText}`); } const data = await response.json(); setPosts(data); } catch (err) { setError(err.message); } }; fetchPosts(); }, []); // 空の依存配列により、コンポーネントがマウントされたときのみ実行 return ( <div> <p>Home</p> <ul> <li><Link to="/about">About</Link></li> <li><Link to="/contact">Contact</Link></li> </ul> <h2>Posts</h2> {error ? ( <p style={{ color: "red" }}>Failed to fetch posts: {error}</p> ) : posts.length > 0 ? ( <ul> {posts.map((post) => ( <li key={post.id}> {post.id}: {post.title} </li> ))} </ul> ) : ( <p>Loading...</p> )} </div> ); };
■データの投稿 以下はChatGPTによるコード。
import { Link, useNavigate } from "react-router-dom"; import { useState } from "react"; export const Home = () => { const [title, setTitle] = useState(""); const [body, setBody] = useState(""); //const navigate = useNavigate(); // 投稿後にリダイレクトさせる場合 const handleSubmit = async (e) => { e.preventDefault(); try { // POSTリクエストを送信 const response = await fetch("http://localhost/~test/react/post/post.php", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded", }, body: new URLSearchParams({ title, body }).toString(), }); if (response.ok) { console.log("データが正常に送信されました"); } else { console.error("データ送信に失敗しました", response.statusText); } } catch (error) { console.error("エラーが発生しました", error); } console.log("Title:", title); console.log("Body:", body); //navigate("/complete"); // 投稿後にリダイレクトさせる場合 }; return ( <div> <p>Home</p> <ul> <li><Link to="/about">About</Link></li> <li><Link to="/contact">Contact</Link></li> </ul> <form onSubmit={handleSubmit}> <dl className="mb-2"> <dt>タイトル</dt> <dd><input type="text" name="title" value={title} onChange={(e) => setTitle(e.target.value)} className="border-2 p-1 block w-64" /></dd> <dt>本文</dt> <dd><textarea name="body" value={body} onChange={(e) => setBody(e.target.value)} className="border-2 p-1 block w-64 h-28" /></dd> </dl> <p> <button type="submit" className="border-2 p-2">作成</button> </p> </form> </div> ); };
post.php の内容は以下のとおり。 同じ階層に post.log があり、そこに投稿データが記録される。
<?php header('Access-Control-Allow-Origin: http://localhost:3000'); // フロントエンドのオリジンを許可 header('Access-Control-Allow-Methods: POST'); // 許可するHTTPメソッド header('Access-Control-Allow-Headers: Content-Type'); // 許可するヘッダー $title = $_POST['title']; $body = $_POST['body']; if (file_put_contents('post.log', "title=" . $title . "\nbody=" . $body . "\n") === false) { exit('NG'); } echo 'OK';
「Access-Control-Allow-Origin」などについては以下を参照 なんとなく CORS がわかる...はもう終わりにする。 #JavaScript - Qiita https://qiita.com/att55/items/2154a8aad8bf1409db2b

Advertisement