《react-router-dom原始碼揭祕》系列
1. Context - React跨元件訪問資料的利器
3. react-router-dom原始碼揭祕 - BrowserRouter
今天再給大家帶來一篇翻譯文章。原文來自react-router-dom官網
這篇文章,是我們react-router-dom原始碼揭祕系列的第二篇文章。同樣是預備知識。
想看第一篇文章的客官請走這邊。Context - React跨元件訪問資料的利器
基本元件
React Router中有三類元件:
- router 元件(BrowserRouter,HashRouter)
- route matching 元件(Route,Switch)
- navigation 元件(Link)
使用react-router-dom之前,我們需要在工程路徑下安裝這個包
npm install react-router-dom
複製程式碼
安裝完成後,上面所列出的這些元件,我們可以通過react-router-dom得到。
import { BrowserRouter, Route, Link } from "react-router-dom";
複製程式碼
Routers
基於React Router的web應用,根元件應該是一個router元件(BrowserRouter,HashRouter)。 專案中,react-router-dom提供了和兩種路由。兩種路由都會建立一個history物件。如果我們的應用有伺服器響應web的請求,我們通常使用<BrowserRouter>元件; 如果使用靜態檔案伺服器,則我們應該使用<HashRouter>元件
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
holder
);
複製程式碼
路由匹配
react-router-dom中有兩個匹配路由的元件:<Route> 和 <Switch>.
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/>元件會一直渲染
複製程式碼
我們可以在元件樹的任何位置放置<Route>元件。但是更常見的情況是將幾個<Route>寫在一起。<Switch>元件可以用來將多個<Route>“包裹”在一起。
多個元件在一起使用時,並不強制要求使用<Switch>元件,但是使用<Switch>元件卻是非常便利的。<Switch>會迭代它下面的所有<Route>子元件,並只渲染第一個路徑匹配的<Route>。
<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 Rendering Props
<Route>匹配時所顯示的元件,有三種寫法:
具體用法可以參照<Route>文件,這裡我們先簡單介紹一下component和render兩種方法。
component
在使用<Route>時,如果我們想渲染的內容已經有對應的元件,則可以直接使用component的方法。例如:
<Route path="/user/:username" component={User} />;
function User({ match }) {
return <h1>Hello {match.params.username}!</h1>;
}
複製程式碼
render
render方法直接使用一個行內函數來渲染內容。
// convenient inline rendering
<Route path="/home" render={() => <div>Home</div>}/>
複製程式碼
注意:
不要將component屬性設定為一個函式,然後在其內部渲染元件。這樣會導致已經存在的元件被解除安裝,然後重寫建立一個新元件,而不是僅僅對元件進行更新。
const Home = () => <div>Home</div>;
const App = () => {
const someVariable = true;
return (
<Switch>
{/* these are good */}
<Route exact path="/" component={Home} />
<Route
path="/about"
render={props => <About {...props} extra={someVariable} />}
/>
{/* do not do this */}
<Route
path="/contact"
component={props => <Contact {...props} extra={someVariable} />}
/>
</Switch>
);
};
複製程式碼
Navigation
React Router提供了一個元件用來在應用中新增link。當<Link>渲染時,一個<a>標籤在html頁面中被建立出來。
<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>元件的to屬性指定的位置上。
<Route exact path="/" render={() => (
loggedIn ? (
<Redirect to="/dashboard"/>
) : (
<PublicHomePage/>
)
)}/>
複製程式碼