118. Pascal‘s Triangle(Leetcode每日一題-2020.12.06)
安裝並引入
安裝
npm install react-router-dom
引入
import { BrowserRouter, Route, Link } from 'react-router-dom'
基本元件
React Router 中有三類元件:
- router 元件(BrowserRouter, HashRouter)
- route matching 元件(Route,Switch)
- navigation 元件(Link,NavLink)
Router 元件
基於 React Router 的 Web 應用,其根元件應該是一個 router 元件(BrowserRouter,HashRouter)。專案中, react-router-dom
<BrowserRouter>
元件,如果使用靜態檔案伺服器,則我們應該使用 <HashRouter>
元件。
// 我們可以直接在 index 入口檔案中引入 BrowserRouter 元件 import { BrowserRouter } from "react-router-dom"; ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter>, holder );
路由匹配
react-router-dom中有兩個匹配路由的元件:
import { Route, Switch } from "react-router-dom";
路由匹配是通過將 Route
元件的 path 屬性與當前的 location
的 pathname
進行比較來完成的。當一個 <Route>
與當前位址列中的路徑匹配了,那麼它所對應的元件內容將被渲染出來;如果不匹配,則渲染 null。當一個 <Route>
沒有 path 屬性,那麼它所對應的內容將總是會被渲染出來。
// 當 location = { pathname: '/about' } <Route path='/about' component={About}/> // 路徑匹配成功,渲染 <About/>元件 <Route path='/contact' component={Contact}/> // 路徑不匹配,渲染 null <Route component={Always}/> // 該元件沒有path屬性,其對應的<Always/>元件會一直渲染
我們可以在元件樹的任何位置放置
多個元件在一起使用時,並不強制要求使用
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
</Switch>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
{/* 如果上面的Route的路徑都沒有匹配上,則 <NoMatch>被渲染,我們可以在此元件中返回404 */}
<Route component={NoMatch} />
</Switch>
Route 渲染屬性
component
在使用
<Route path="/user/:username" component={User} />;
function User({ match }) {
return <h1>Hello {match.params.username}!</h1>;
}
render
render 屬效能使我們便捷地渲染內聯元件或者是巢狀元件,我們可以給這個屬性傳入一個函式,當路由的路徑匹配時呼叫。同時,render 屬性也會接受所有的 Route 傳入的引數。
//內聯方式
<Route path="path" render={() => <div>這是內聯元件寫法</div>} />
//巢狀組合方式
<Route path="path" render={ props => (
<ParentComp>
<Comp {...props} />
</ParentComp>
) />
children
children 屬性接收一個函式作為其值,當 Route 中有 children
屬性時,不管當前的路徑是否與 Route 匹配,該函式都會執行,同時,children 屬性也會接收 Route 傳入的所有的引數。
<Route path="path" children={ props => (
<div className={props.match? "active": ''}>
<Link to="path" />
</div>
) />
注意: 不要將 component 屬性設定為一個函式,然後在其內部渲染元件。這樣會導致已經存在的元件被解除安裝,然後重寫建立一個新的元件,而不是僅僅對元件進行更新。
注意
在使用 Route 的這三個屬性渲染元件時,當三個屬性同時存在會有優先順序的問題,正常情況下使用其中的一個屬性就可以,但是如果當他們同時存在,優先渲染 children 的值,其他的不會渲染;其次,如果 component 和 render 同時存在,那麼會渲染 component,而不會渲染 render 屬性。
children > component > render
navigation 元件
React Router 提供了<Link>
元件用來在應用中新增跳轉連結。 預設會被渲染為 a 標籤。
<Link to="/">Home</Link>
// <a href='/'>Home</a>
<NavLink>
元件是一個特殊的 <Link>
元件。當它的 path
與當前 location
匹配時,可以自定義其樣式來表示當前頁面位置。
// location = { pathname: '/react' }
<NavLink to="/react" activeClassName="hurray">
React
</NavLink>
// <a href='/react' className='hurray'>React</a>
Redirect 元件
當頁面需要重定向時,我們可以使用 <Redirect>
元件。當一個 <Redirect>
元件被渲染時,頁面將被渲染到 <Redirect>
元件的 to 屬性指定的位置上。
// 如果是登入狀態,則跳轉到 dashboard 頁面,否則是公共頁面
<Route exact path="/" render={() => (
loggedIn ? (
<Redirect to="/dashboard"/>
) : (
<PublicHomePage/>
)
)}/>
使用 Switch 包裹和直接使用 Route 的區別?
<Switch>
渲染第一個被 location 匹配到的並且作為子元素的<Route>
或者<Redirect>
<Switch>
是唯一的,因為它僅僅只會渲染一個路徑。相比之下,不使用 <Switch>
包裹的情況下,每一個被 location 匹配的 <Route>
都將會被渲染。
<Route path='/home' component={Home}></Route>
<Route path='/home/user' component={About}></Route>
<Route component={Main}></Route>
如上述程式碼,如果 url 是 home,那麼 <Home>
<About>
<Main>
等元件都會被渲染,因為他們的 path 都被匹配到。
然而有時我們只想選擇性的渲染一個 <Route>
。如果 Url 是 /home ,但我們並不想也匹配到 /home/user (或者顯示給我們的 404 頁面)。我們可以利用 Switch 來處理。
<Switch>
<Route exact path='/home' component={Home}></Route>
<Route path='/home/user' component={User}></Route>
<Route path='/about' component={About}></Route>
<Route component={Main}></Route>
</Switch>
現在,如果 url 是 /home, <Switch>
將會開始尋找相匹配的 <Route>
。<Route path="/home" />
將會被匹配到,緊接著 <Switch>
會停止繼續匹配並且渲染 <Home>
。同理,如果URL是/home/user,那麼
exact
精確匹配的意思,如果 Route 中不新增exact
那麼就會進行模糊匹配,可能會匹配多個路由,渲染多個元件
參考文章: