HTML5テクニカルノート
Create React App + React Router入門 03: ルーティングを入れ子にする
- ID: FN2005003
- Technique: ECMAScript 2015
- Library: React 16.13.1 / React Router 5.1.2
React Routerのルーティングは入れ子にできます。とくにむずかしいことは考えることなく、ルーティングしたコンポーネントの中に、お約束どおりのルーティングを定めればよいのです。前回の「Create React App + React Router入門 02: ページの遷移と状態の保持」でアプリケーションのモジュール(src/App.js
)に書いたコード001に手を加えてゆきましょう。
01 コンポーネントにテキストを加える
入れ子のルーティングは、ふたつ目の設定のコンポーネント(Settings2
)に加えるつもりです。コンポーネントProducts
のタイトルカラーだけでなく、別のテキストも加えられるようにします。そこで、そのテキストをつぎのようにuseState()
で状態変数(text2
)にもたせました。まずは、コンポーネントにこの新たなテキストが加わります(図001)。
src/App.jsfunction App() { const [text2, setText2] = useState('sample text'); return ( <Router> <Switch> <Route path="/products"> {/* <Products color2={color2} /> */} <Products color2={color2} text2={text2} /> </Route> </Switch> </Router> ); } const Products = (props) => ( <> <h2 style={{color: props.color2}}>Products</h2> <p> {props.text2 ? props.text2 : null} </p> </> );
図001■コンポーネントに状態変数のテキストが加わった
02 入れ子のルーティングを定める
入れ子のルーティングは、ルーティング先のコンポーネントの中にさらにルーティングを定めるというだけです。それ以外、とくに変わったところはありません。ルーティングは<Route>
と<Switch>
で決めればよく、遷移には<Link>
を使ってください。ふたつ目の設定画面のコンポーネント(Settings2
)はつぎのように書き替え、ふたつのルーティング先のデータは配列(settings
)で定めました。
src/App.jsfunction App() {function App() { const [text2, setText2] = useState('sample text'); return ( <Router> <Switch> <Route path="/settings2"> {/* <Settings2 setColor2={setColor2} /> */} <Settings2 setColor2={setColor2} setText2={setText2} /> </Route> </Switch> </Router> ); } /* const Settings2 = (props) => ( <> <h2>Settings2</h2> <input type="text" onChange={(event) => props.setColor2(event.target.value)} /> <p><Link to="/settings"><< prev</Link></p> </> ); */ const Settings2 = (props) => { const settings = [ {name: 'Color', path: 'color', setValue: props.setColor2}, {name: 'Text', path: 'text', setValue: props.setText2}, ]; return ( <> <h2>Settings2</h2> <ul> {settings.map((setting, id) => ( <li key={id}> <Link to={'/settings2/' + setting.path}>{setting.name}</Link> </li> ))} </ul> <Switch> {settings.map((setting, id) => ( <Route path={'/settings2/' + setting.path} key={id}> <Details name={setting.name} path={setting.path} setValue={setting.setValue} /> </Route> ))} <Route path={'/settings2/'}> <h3>Pleasse select a setting.</h3> </Route> </Switch> <p><Link to="/settings"><< prev</Link></p> </> ); };
これでProducts
コンポーネントのタイトルの色だけでなく、新たに加えたテキストも動的に書き替えられます(図002)。手直ししたアプリケーションモジュールsrc/App.js
の記述全体は、以下のコード001のとおりです。また、サンプル001をCodeSandboxに公開しました。
図002■タイトルカラーだけでなくテキストが動的に書き替えられる
→
コード001■設定画面で入れ子のルーティングを定める
src/App.js
import React, { useState } from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from 'react-router-dom';
import './App.css';
function App() {
const [color, setColor] = useState('black');
const [color2, setColor2] = useState('black');
const [text2, setText2] = useState('sample text');
return (
<Router>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/products">Products</Link>
</li>
<li>
<Link to="/settings">Settings</Link>
</li>
</ul>
</nav>
<Switch>
<Route path="/products">
<Products color2={color2} text2={text2} />
</Route>
<Route path="/settings">
<Settings setColor={setColor} />
</Route>
<Route path="/settings2">
<Settings2 setColor2={setColor2} setText2={setText2} />
</Route>
<Route path="/">
<Home color={color} />
</Route>
</Switch>
</Router>
);
}
const Home = (props) => (
<h2 style={{color: props.color}}>Home</h2>
);
const Products = (props) => (
<>
<h2 style={{color: props.color2}}>Products</h2>
<p>
{props.text2 ? props.text2 : null}
</p>
</>
);
const Settings = (props) => (
<>
<h2>Settings</h2>
<input type="text"
onChange={(event) => props.setColor(event.target.value)}
/>
<p><Link to="/settings2">next >></Link></p>
</>
);
const Settings2 = (props) => {
const settings = [
{name: 'Color', path: 'color', setValue: props.setColor2},
{name: 'Text', path: 'text', setValue: props.setText2},
];
return (
<>
<h2>Settings2</h2>
<ul>
{settings.map((setting, id) => (
<li key={id}>
<Link to={'/settings2/' + setting.path}>{setting.name}</Link>
</li>
))}
</ul>
<Switch>
{settings.map((setting, id) => (
<Route path={'/settings2/' + setting.path} key={id}>
<Details name={setting.name} path={setting.path} setValue={setting.setValue} />
</Route>
))}
<Route path={'/settings2/'}>
<h3>Pleasse select a setting.</h3>
</Route>
</Switch>
<p><Link to="/settings"><< prev</Link></p>
</>
);
};
const Details = (props) => {
return (
<label>
{props.name}
<input type="text"
onChange={(event) => props.setValue(event.target.value)}
/>
</label>
);
};
export default App;
サンプル001■React Router 04: Nested routing
Create React App + React Router入門
- Create React App + React Router入門 01: ルーティングを定める
- Create React App + React Router入門 02: ページの遷移と状態の保持
- Create React App + React Router入門 03: ルーティングを入れ子にする
- Create React App + React Router入門 04: フックuseRouteMatch()とuseHistory()を使う
作成者: 野中文雄
作成日: 2020年05月19日
Copyright © 2001-2020 Fumio Nonaka. All rights reserved.