æçš¿è
@ pshrmnâ¬
ãªãªãžãã«èšäº â¬
èªæžæé ïŒ
10åReact Router v4ã¯ã人æ°ã®ããReactã¢ããªã³ã®åèšèšãããããŒãžã§ã³ã§ãã 以åã®ããŒãžã§ã³ã®ãã©ãããã©ãŒã äŸåã®ã«ãŒãæ§æã¯åé€ããããã¹ãŠãã·ã³ãã«ãªã³ã³ããŒãã³ãã«ãªããŸããã
ãã®ãã¥ãŒããªã¢ã«ã§ã¯ãReact Routerã§Webãµã€ããæ§ç¯ããããã«å¿
èŠãªãã¹ãŠãã«ããŒããŠããŸãã å°å
ã®ã¹ããŒãããŒã ã®ãµã€ããäœæããŸãã
ãã¢ãèŠããã§ããïŒ
èšçœ®
React Router v4ã¯3ã€ã®ããã±ãŒãžã«åå²ãããŸããã
react-router
router-dom
react-router-native
react-router
ã¯ã2ã€ã®ç°å¢ïŒBrowserããã³react-nativeïŒã§äœæ¥ããããã®åºæ¬çãªæ©èœãšã³ã³ããŒãã³ããæäŸããŸã
ãã©ãŠã¶ã«è¡šç€ºããããµã€ããäœæããã®ã§ã
react-router-dom
䜿çš
react-router-dom
å¿
èŠããããŸãã
react-router-dom
ã¯ãã¹ãŠã®æ©èœã
react-router
ãããšã¯ã¹ããŒãããããã
react-router-dom
ãã€ã³ã¹ããŒã«
react-router-dom
ã ãã§ãã
npm install --save react-router-dom
ã«ãŒã¿ãŒ
ãããžã§ã¯ããéå§ãããšãã䜿çšããã«ãŒã¿ãŒã®ã¿ã€ãã決å®ããå¿
èŠããããŸãã ãã©ãŠã¶ãŒãããžã§ã¯ãã«ã¯ã
BrowserRouter
ããã³
HashRouter
ã³ã³ããŒãã³ãããããŸãã
BrowserRouter
ãµãŒããŒã§åçãªã¯ãšã¹ããåŠçãããšãã«äœ¿çšããéçWebãµã€ããããå Žåã¯
HashRouter
ã䜿çšããå¿
èŠããããŸãã
éåžžã
BrowserRouter
ã䜿çšããããšãã
BrowserRouter
ãŸããããµã€ããéçãµãŒããŒïŒ
githubããŒãžãšããŠã®ç¿»èš³ãã ïŒã«ããå Žåã¯ã
HashRouter
ã䜿çšããããšãåé¡ã®è¯ã解決çã§ãã
ãã®ãããžã§ã¯ãã§ã¯ããã¯ãšã³ãã䜿çšããããã
BrowserRouter
ã䜿çšã
BrowserRouter
ã
æŽå²-æŽå²
åã«ãŒã¿ãŒã¯ãçŸåšã®å Žæ[1]ãžã®ãã¹ãæ ŒçŽãã
history
ãªããžã§ã¯ããäœæãããã¹ã®å€æŽãçºçãããšãã«ãµã€ãã€ã³ã¿ãŒãã§ã€ã¹ãåæç»ããŸãã
React Routerã§æäŸãããæ®ãã®æ©èœã¯ãã³ã³ããã¹ããä»ãã
history
ãªããžã§ã¯ãã®å¯çšæ§ã«äŸåããŠãããããã«ãŒã¿ãŒã³ã³ããŒãã³ãå
ã§ã¬ã³ããªã³ã°ããå¿
èŠããããŸãã
泚ïŒç¥å
ãšããŠã«ãŒã¿ãŒã³ã³ããŒãã³ããæããªãReactã«ãŒã¿ãŒã³ã³ããŒãã³ãã¯ãã³ã³ããã¹ããå©çšã§ããªãããæ©èœããŸããã
ã«ãŒã¿ãŒã®ã¬ã³ããªã³ã°
Routerã³ã³ããŒãã³ãã¯ãåãšããŠ1ã€ã®èŠçŽ ã®ã¿ãæ³å®ããŠããŸãã ãã®æ¡ä»¶äžã§äœæ¥ããã«ã¯ãã¢ããªã±ãŒã·ã§ã³å
šäœãã¬ã³ããªã³ã°ãã<App />ã³ã³ããŒãã³ããäœæãããšäŸ¿å©ã§ãïŒããã¯ãµãŒããŒã¬ã³ããªã³ã°ã«ãéèŠã§ãïŒã
import { BrowserRouter } from 'react-router-dom'; ReactDOM.render(( <BrowserRouter> <App /> </BrowserRouter> ), document.getElementById('root'))
ã¢ããªã³ã³ããŒãã³ã
ã¢ããªã±ãŒã·ã§ã³ã¯ã2ã€ã®éšåã«åå²ãã
<App/>
ã³ã³ããŒãã³ãã§å§ãŸããŸãã
<Header/>
ã«ã¯ããã²ãŒã·ã§ã³ãªã³ã¯ãå«ãŸãã
<Main/>
ã«ã¯ã«ãŒãã®ã³ã³ãã³ããå«ãŸããŸãã
ã«ãŒã
<Route/>
ã³ã³ããŒãã³ãã¯ãReact Routerã®äž»èŠãªæ§æèŠçŽ ã§ãã URLã®ãã¹åã«å¿ããŠèŠçŽ ãã¬ã³ããªã³ã°ããå¿
èŠãããå Žåã¯ã
<Route/>
ã³ã³ããŒãã³ãã䜿çšããå¿
èŠããããŸã
ãã¹-ãã¹
<Route />
ã¯ãç¹å®ã®ãã¹ãèšè¿°ããlocation.pathnameã«ãããããå°éå
·ãšããŠ
path
ãåã
path
ã
<Route path='/roster'/>
äžèšã®äŸã§ã¯ã
<Route/>
ã¯/ roster [2]ã§å§ãŸãlocation.pathnameãšäžèŽããŸãã çŸåšã®location.pathnameãpropãã¹ã«ããžãã£ãã«ãããããããšãã³ã³ããŒãã³ããã¬ã³ããªã³ã°ãããããããäžèŽããªãå ŽåãRouteã¯äœãã¬ã³ããªã³ã°ããŸãã[3]ã
<Route path='/roster'/>
泚ïŒãã¹ã«é¢ããŠã¯ãReact Routerã¯ãã¡ã€ã³ã®ãªããã¹ã®ã¿ãèæ
®ããŸãã ããã¯ãã¢ãã¬ã¹ã§æ¬¡ã®ããšãæå³ããŸãã
http://www.example.com/my-projects/one?extra=false
React Routerã¯
/my-projects/one
ã®ã¿ã衚瀺ããŸã
ãã¹ãããã³ã°
npm
path-to-regexp
ããã±ãŒãžã¯ãpropãã¹ãæ£èŠè¡šçŸã«ã³ã³ãã€ã«ããlocation.pathnameãšç
§åããŸãã ãã¹è¡ã«ã¯ãããã§èª¬æãããããè€éãªæžåŒèšå®ãªãã·ã§ã³ããããŸãã
ããã¥ã¡ã³ããèªãããšãã§ã
ãŸã ã
ãã¹ãäžèŽãã
match
ãããããã£ãå«ã
match
ãªããžã§ã¯ããäœæãããŸãã
- url-çŸåšã®location.pathnameã®ãããã³ã°ãããéšå
- path -Routeã³ã³ããŒãã³ãã®ãã¹
- isExact-ã«ãŒãã®ãã¹=== location.pathname
- params-ãªããžã§ã¯ãã«ã¯ãpath-to-regexpã¢ãžã¥ãŒã«ãè¿ããã¹ããã®å€ãå«ãŸããŸã
æ³šïŒ ã«ãŒããã¹ã¿ãŒã§éãã§ãäžèŽãªããžã§ã¯ããã©ã®ããã«äœæããããã確èªã§ããŸãã
泚ïŒã«ãŒãã®ãã¹ã¯çµ¶å¯Ÿãã¹ã§ãªããã°ãªããŸãã[4]ã
ã«ãŒããäœæãã
Route
ã³ã³ããŒãã³ãã¯ã«ãŒã¿ãŒå
ã®ã©ãã«ã§ãé
眮ã§ããŸãããåãå Žæã«äœãã¬ã³ããªã³ã°ãããã決å®ããå¿
èŠãããå ŽåããããŸãã ãã®å Žåãã«ãŒãã°ã«ãŒãåã³ã³ããŒãã³ã-
<Switch/>
ãŸãã
<Switch/>
ã¯åã³ã³ããŒãã³ããå埩åŠçããlocation.pathnameã«äžèŽããæåã®ã³ã³ããŒãã³ãã®ã¿ãã¬ã³ããªã³ã°ããŸãã
ç§ãã¡ã®ãŠã§ããµã€ãã«ã¯ããããããããã¹ããããŸãïŒ
- / -ããŒã ããŒãž
- /åç°¿ -ã³ãã³ãããŒãž
- /åç°¿/ïŒçªå· -çªå·ã«ãããã¬ãŒã€ãŒãããã£ãŒã«ããŒãž
- /ã¹ã±ãžã¥ãŒã« -ããŒã ã¹ã±ãžã¥ãŒã«
ã¢ããªã±ãŒã·ã§ã³ã§ãã¹ããããããããã«å¿
èŠãªããšã¯ããããããpropãã¹ã䜿çšããŠRouteã³ã³ããŒãã³ããäœæããããšã ãã§ãã
<Switch> <Route exact path='/' component={Home}/> {/* /roster /roster/:number /roster */} <Route path='/roster' component={Roster}/> <Route path='/schedule' component={Schedule}/> </Switch>
Routeã³ã³ããŒãã³ãã¯äœãã¬ã³ããªã³ã°ããŸããïŒ
ã«ãŒãã«ã¯ãå°éå
·ã®ãã¹ãlocation.pathnameãšäžèŽãããããšã§ã¬ã³ããªã³ã°ããæ¹æ³ã説æãã3ã€ã®å°éå
·ããããå°éå
·ã®1ã€ã ããRouteã§è¡šãå¿
èŠããããŸãã
- component -Reactã³ã³ããŒãã³ãã ã«ãŒãããã¹ã«äžèŽãããšãæž¡ãããã³ã³ããŒãã³ããè¿ããŸãïŒReact.createElementé¢æ°ã䜿çšïŒã
- renderã¯ãReactèŠçŽ ãè¿ãå¿
èŠãããé¢æ°ã§ãã ãã¹å
ã®äžèŽãæºãããããšãã«åŒã³åºãããŸãã ã¬ã³ããªã³ã°ã¯ã³ã³ããŒãã³ãã«éåžžã«äŒŒãŠããŸãããã€ã³ã©ã€ã³ã¬ã³ããªã³ã°ãšå¿
èŠãªpropsèŠçŽ ã®çœ®æã«äœ¿çšãããŸã[5]ã
- children-åã®2ã€ã®å°éå
·ãšã¯ç°ãªãããã¹ãããããããŠãããã©ããã«é¢ä¿ãªããåã¯åžžã«è¡šç€ºãããŸãã
<Route path='/page' component={Page} /> const extraProps = { color: 'red' } <Route path='/page' render={(props) => ( <Page {...props} data={extraProps}/> )}/> <Route path='/page' children={(props) => ( props.match ? <Page {...props}/> : <EmptyPage {...props}/> )}/>
äžè¬çãªç¶æ³ã§ã¯ãã³ã³ããŒãã³ãã䜿çšãããã¬ã³ããªã³ã°ããŸãã children propã¯äœ¿çšã§ããŸãããpathãlocation.pathnameãšäžèŽããªãå Žåã¯äœãããªãããšãæåã§ãã
ã¬ã³ããªã³ã°ããã
Route
ã¯ãããã€ãã®å°éå
·ãæž¡ãããŸãã
match
-
path
ã
location.pathname
ã
location
ãªããžã§ã¯ã[6]ããã³
history
ãªããžã§ã¯ãïŒã«ãŒãèªäœã«ãã£ãŠäœæïŒ[7]ã«ããããããªããžã§ã¯ãã
ã¡ã€ã³
次ã«ãã«ãŒã¿ãŒã®åºæ¬æ§é ã«ã€ããŠèª¬æããŸãã ã«ãŒãããããã³ã°ããã ãã§ãã ãã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ã
<Main/>
ã³ã³ããŒãã³ãå
ã§
<Switch/>
ã³ã³ããŒãã³ããš
<Route/>
ã³ã³ããŒãã³ãã䜿çšããå
éšã§
path
äžèŽããçæãããHTMLãé
眮ããŸãã
<Main/>
ããŒãïŒããŒãïŒã®DOM
import { Switch, Route } from 'react-router-dom' const Main = () => ( <main> <Switch> <Route exact path='/' component={Home}/> <Route path='/roster' component={Roster}/> <Route path='/schedule' component={Schedule}/> </Switch> </main> )
泚ïŒã¡ã€ã³ããŒãž
ã® Route
ã«ã¯prop
exact
ãå«ãŸããŠããããããã¹ãå³å¯ã«æ¯èŒãããŸãã
ç¶æ¿ãããã«ãŒã
ãã¬ãŒã€ãŒãããã¡ã€ã«
/roster/:number
<Switch/>
å«ãŸããŠããŸããã 代ããã«ããã¹ã
/roster
å§ãŸããã³ã«ã¬ã³ããªã³ã°ããã
<Roster/>
ã³ã³ããŒãã³ãã«ãã£ãŠã¬ã³ããªã³ã°ãããŸãã
Roster
ã³ã³ããŒãã³ãã§ã¯ã2ã€ã®ãã¹ã®ã³ã³ããŒãã³ããäœæããŸãã
- /åç°¿ -æ£ç¢ºãªå°éå
·ä»ã
- / roster /ïŒnumber-ãã®ã«ãŒãã¯ã/ rosterã®åŸã«ãã£ããããããã¹ãã©ã¡ãŒã¿ãŒã䜿çšããŸã
const Roster = () => ( <Switch> <Route exact path='/roster' component={FullRoster}/> <Route path='/roster/:number' component={Player}/> </Switch> )
å
±éã³ã³ããŒãã³ããæã€ã«ãŒããã°ã«ãŒãåãããšäŸ¿å©ã§ããããã«ããã芪ã«ãŒããç°¡çŽ åãããè€æ°ã®ã«ãŒãã«é¢é£ããã³ã³ãã³ãã衚瀺ã§ããŸãã
ããšãã°ã
<Roster/>
ã¯ã
/roster
ã§å§ãŸããã¹ãŠã®ã«ãŒãã«è¡šç€ºãããããããŒã§ã¬ã³ããªã³ã°ã§ããŸãã
const Roster = () => ( <div> <h2>This is a roster page!</h2> <Switch> <Route exact path='/roster' component={FullRoster}/> <Route path='/roster/:number' component={Player}/> </Switch> </div> )
ãã¹å
ã®ãã©ã¡ãŒã¿ãŒ
å€æ°ã䜿çšããŠäœããã®æ
å ±ãååŸããå¿
èŠãããå ŽåããããŸãã ããšãã°ããã¬ãŒã€ãŒçªå·ãååŸããå¿
èŠããããã¬ãŒã€ãŒãããã¡ã€ã«ã«ãŒãã ãããè¡ãã«ã¯ããã©ã¡ãŒã¿ãæ¯æ±
path
è¿œå ããŸãã
:number
/roster/:number
è¡
:number
éšåã«
/roster/:number
ã
match.params.number
ãšã
/roster/
åŸã®
path
éšåãå€æ°ãšããŠåä¿¡ããã
match.params.number
æ ŒçŽãã
match.params.number
ã ããšãã°ãpath
/roster/6
ããã©ã¡ãŒã¿ãŒã䜿çšããŠæ¬¡ã®ãªããžã§ã¯ããçæããŸãã
{ number: '6'
<Player/>
ã³ã³ããŒãã³ãã¯
props.match.params
ã䜿çšããŠãã¬ã³ããªã³ã°ããå¿
èŠãããæ
å ±ãååŸããŸãã
æ³šïŒ path-to-regexpã§
ãã¹ãªãã·ã§ã³ã®è©³çŽ°ã確èªã§ããŸãã
<Player/>
ã³ã³ããŒãã³ãã«å ããŠãåœç€Ÿã®Webãµã€ãã§ã¯
<FullRoster/>
ã
<Schedule/>
ããã³
<Home/>
ãŸãã
const FullRoster = () => ( <div> <ul> { PlayerAPI.all().map(p => ( <li key={p.number}> <Link to={`/roster/${p.number}`}>{p.name}</Link> </li> )) } </ul> </div> ) const Schedule = () => ( <div> <ul> <li>6/5 @ </li> <li>6/8 vs </li> <li>6/14 @ </li> </ul> </div> ) const Home = () => ( <div> <h1> !</h1> </div> )
åç
§è³æ
æåŸã«ãç§ãã¡ã®ãµã€ãã«ã¯ããŒãžéã®ããã²ãŒã·ã§ã³ãå¿
èŠã§ãã éåžžã®ãªã³ã¯ãäœæãããšãããŒãžããªããŒããããŸãã React Routerã¯ãåèµ·åãé²ã
<Link/>
ã³ã³ããŒãã³ãã䜿çšããŠãã®åé¡ã解決ããŸãã
<Link/>
ãã¯ãªãã¯ãããšãURLãæŽæ°ãããReact Routerã¯ããŒãžãæŽæ°ããã«ç®çã®ã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããŸãã
import { Link } from 'react-router-dom' const Header = () => ( <header> <nav> <ul> <li><Link to='/'>Home</Link></li> <li><Link to='/roster'>Roster</Link></li> <li><Link to='/schedule'>Schedule</Link></li> </ul> </nav> </header> )
<Link/>
ã¯prop
to
䜿çš
to
ãŠãè¡ãå
ã®URLãèšè¿°ããŸãã Prop toã¯ãæååãŸãã¯å Žæãªããžã§ã¯ãïŒãã¹åãæ€çŽ¢ãããã·ã¥ãç¶æ
ã®ããããã£ã§æ§æãããïŒã«ããããšãã§ããŸãã ãããæååã®å Žåããã±ãŒã·ã§ã³ãªããžã§ã¯ãã«å€æãããŸãã
<Link to={{ pathname: '/roster/7' }}>Player #7</Link>
æ³šïŒ <Link/>
ã³ã³ããŒãã³ãã®ãã¹ã¯çµ¶å¯Ÿãã¹ã§ãªããã°ãªããŸãã[4]ã
å®æœäŸ
ãŠã§ããµã€ãã®ãã¹ãŠã®ã³ãŒãã¯ãcodepenã®
ãã®ã¢ãã¬ã¹ã§å
¥æã§ããŸãã
ã«ãŒãã®æºåãã§ããŸããïŒ
ããã§ãWebã¢ããªã±ãŒã·ã§ã³ã®ã«ãŒãã£ã³ã°ã®è©³çŽ°ã«é£ã³èŸŒãæºåãã§ããããšãé¡ã£ãŠããŸãã
ç¬èªã®Webã¢ããªã±ãŒã·ã§ã³ïŒ
<BrowserRouter.>, <Route.>, and <Link.>
ïŒãäœæãããšãã«å¿
èŠãšãªãæãåºæ¬çãªã³ã³ããŒãã³ãã䜿çšããŸããããããã§ã¯èª¬æãããŠããªãã³ã³ããŒãã³ããšãããããããã€ããããŸãã 幞ããªããšã«ãReact Routerã«ã¯åªãã
ããã¥ã¡ã³ãããããã³ã³ããŒãã³ããå°éå
·ã®ãã詳现ãªèª¬æãèŠã€ããããšãã§ããŸãã ããã¥ã¡ã³ãã«ã¯ããœãŒã¹ã³ãŒããå«ãå®çšçãªäŸãèšèŒãããŠããŸãã
説æ
[1]-ãã±ãŒã·ã§ã³ãªããžã§ã¯ãã¯ãURLã®ããŸããŸãªéšåãèšè¿°ããŸã
[2]-ãã¹ãªãã§
<Route/>
ã³ã³ããŒãã³ãã䜿çšã§ããŸãã ããã¯ã
context
ä¿åãããŠããã¡ãœãããšå€æ°ãæž¡ãã®ã«äŸ¿å©ã§ãã
[3]-propã®
children
ã䜿çšããå Žåãpathãšlocation.pathnameãäžèŽããªãå Žåã§ããã«ãŒããã¬ã³ããªã³ã°ãããŸãã
[4]-
<Route/>
ããã³
<Link/>
çžå¯Ÿãã¹ã§äœæ¥ãé²è¡äžã§ãã çžå¯Ÿ
<Link/>
èŠãç®ãããè€éã§ããçŸåšã®URLã§ã¯ãªãã芪ã®
match
ãªããžã§ã¯ãã䜿çšããŠè§£æ±ºããå¿
èŠããããŸãã
[5]-ããã¯ã¹ããŒãã¬ã¹ã³ã³ããŒãã³ãã§ãã å
éšã«ã¯
render
ãš
component
éã«å€§ããªéãããã
component
ã ã³ã³ããŒãã³ãã¯
React.createElement
ã䜿çšããŠã³ã³ããŒãã³ããäœæãã
render
é¢æ°ãšããŠäœ¿çšãããŸãã ã€ã³ã©ã€ã³é¢æ°ãå®çŸ©ããŠ
props
ãæž¡ããšã
render
é¢æ°ã䜿çšãããããã¯ããã«é
ããªããŸãã
<Route path='/one' component={One}/>
[6]-ã³ã³ããŒãã³ã
<Route/> <Switch/>
ã¯äž¡æ¹ãšãæ¯æ±ã®äœçœ®ã䜿çšã§ããŸãã ããã«ãããå®éã«çŸåšã®URLãšã¯ç°ãªããã¹ã«ãããããããšãã§ããŸãã
[7]
staticContext
ãéä¿¡ããŸããããµãŒããŒäžã§ã¬ã³ããªã³ã°ããå Žåã«ã®ã¿åœ¹ç«ã¡ãŸãã