您好,登錄后才能下訂單哦!
初試ReactRouterv4 要注意什么,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
距離React Router v4 正式發(fā)布也已經(jīng)過(guò)去三個(gè)月了,這周把一個(gè)React的架子做了升級(jí),之前的路由用的還是v2.7.0版的,所以決定把路由也升級(jí)下,正好“嘗嘗鮮”...
江湖傳言,目前官方同時(shí)維護(hù) 2.x 和 4.x 兩個(gè)版本。(ヾ(??﹏?)??咦,此刻相信機(jī)智如我的你也會(huì)發(fā)現(xiàn),ReactRouter v3 去哪兒了?整丟了??巴拉出鍋了???敢不敢給我個(gè)完美的解釋?。浚┦聦?shí)上 3.x 版本相比于 2.x 并沒(méi)有引入任何新的特性,只是將 2.x 版本中部分廢棄 API 的 warning 移除掉而已。按照規(guī)劃,沒(méi)有歷史包袱的新項(xiàng)目想要使用穩(wěn)定版的 ReactRouter 時(shí),應(yīng)該使用 ReactRouter 3.x。目前 3.x 版本也還處于 beta 階段,不過(guò)會(huì)先于 4.x 版本正式發(fā)布。如果你已經(jīng)在使用 2.x 的版本,那么升級(jí) 3.x 將不會(huì)有任何額外的代碼變動(dòng)。
禮貌性簡(jiǎn)介下
React Router V4 相較于前面三個(gè)版本有根本性變化,首先是遵循 Just Component 的 API 設(shè)計(jì)理念,其次API方面也精簡(jiǎn)了不少,對(duì)新手來(lái)說(shuō)降低了學(xué)習(xí)難度,但如果是對(duì)之前項(xiàng)目的重構(gòu),嗯,簡(jiǎn)直無(wú)**可說(shuō)。本次升級(jí)的主要特點(diǎn)如下:
聲明式(Declarative)
可組合 (Composability)
React Router V4 遵循了 React 的理念: 萬(wàn)物皆組件 。因此 升級(jí)之后的 Route、Link、Switch等都是一個(gè)普通的組件。
React Router V4 基于 Lerna 管理多個(gè) Repository。在此代碼庫(kù)包括:
react-router React Router 核心
react-router-dom 用于 DOM 綁定的 React Router
react-router-native 用于 React Native 的 React Router
react-router-redux React Router 和 Redux 的集成
react-router-config 靜態(tài)路由配置幫助助手
插件初引入
通常我們?cè)?React 的使用中,一般要引入兩個(gè)包, react
和 react-dom
,那么 react-router
和 react-router-dom
是不是兩個(gè)都要引用呢? 注意,前方高能,入門第一坑就在這里 。他們兩個(gè)只要引用一個(gè)就行了,不同之處就是后者比前者多出了 <Link> <BrowserRouter>
這樣的 DOM 類組件。因此我們只需引用 react-router-dom
這個(gè)包就OK了。當(dāng)然,如果搭配 redux
,你還需要使用 react-router-redux
。
主要組件簡(jiǎn)介
在4.0之前版本的 API 中, <Router>
組件的 children 只能是 React Router 提供的各種組件,如 <Route>、<IndexRoute>、<Redirect>
等。而在 React Router 4 中,你可以將各種組件及標(biāo)簽放進(jìn) <Router>
組件中,他的角色也更像是 Redux 中的 <Provider>
。**不同的是 <Provider>
是用來(lái)保持與 store 的更新,而 <Router>
是用來(lái)保持與 location 的同步。**示例如下:
// 示例1 <Router> <div> <ul> <li><Link to="/">首頁(yè)</Link></li> <li><Link to="/about">關(guān)于</Link></li> <li><Link to="/topics">主題列表</Link></li> </ul> <hr/> <Route exact path="/" component={Home}/> <Route path="/about" component={About}/> <Route path="/topics" component={Topics}/> </div> </Router>
Router是所有路由組件共用的底層接口,一般我們的應(yīng)用并不會(huì)使用這個(gè)接口,而是使用高級(jí)的路由:
<BrowserRouter>
:使用 HTML5 提供的 history API 來(lái)保持 UI 和 URL 的同步;
<HashRouter>
:使用 URL 的 hash (例如:window.location.hash) 來(lái)保持 UI 和 URL 的同步;
<MemoryRouter>
:能在內(nèi)存保存你 “URL” 的歷史紀(jì)錄(并沒(méi)有對(duì)地址欄讀寫);
<NativeRouter>
:為使用React Native提供路由支持;
<StaticRouter>
:從不會(huì)改變地址;
TIPS:算是第二坑吧,和之前的Router不一樣,這里 <Router>
組件下只允許存在一個(gè)子元素,如存在多個(gè)則會(huì)報(bào)錯(cuò)。
反面典型在這里:
<Router> <ul> <li><Link to="/">首頁(yè)</Link></li> <li><Link to="/about">關(guān)于</Link></li> <li><Link to="/topics">主題列表</Link></li> </ul> <hr/> <Route exact path="/" component={Home}/> <Route path="/about" component={About}/> <Route path="/topics" component={Topics}/> </Router>
沒(méi)錯(cuò),示例2在沒(méi)有 <div>
爸爸的保護(hù)下,會(huì)報(bào)如下異常信息:
我們知道,Route組件主要的作用就是當(dāng)一個(gè)location匹配路由的path時(shí),渲染某些UI。示例如下:
<Router> <div> <Route exact path="/" component={Home}/> <Route path="/news" component={NewsFeed}/> </div> </Router> // 如果應(yīng)用的地址是/,那么相應(yīng)的UI會(huì)類似這個(gè)樣子: <div> <Home/> </div> // 如果應(yīng)用的地址是/news,那么相應(yīng)的UI就會(huì)成為這個(gè)樣子: <div> <NewsFeed/> </div>
<Route>
組件有如下屬性:
path(string): 路由匹配路徑。(沒(méi)有path屬性的Route 總是會(huì) 匹配);
exact(bool):為true時(shí),則要求路徑與location.pathname必須完全匹配;
strict(bool):true的時(shí)候,有結(jié)尾斜線的路徑只能匹配有斜線的location.pathname;
再次奉上兩個(gè)鮮活的例子:
exact配置:
路徑 | location.pathname | exact | 是否匹配 |
---|---|---|---|
/one | /one/two | true | 否 |
/one | /one/two | false | 是 |
strict配置:
路徑 | location.pathname | strict | 是否匹配 |
---|---|---|---|
/one/ | /one | true | 否 |
/one/ | /one/ | true | 是 |
/one/ | /one/two | true | 是 |
同時(shí),新版的路由為 <Route>
提供了三種渲染內(nèi)容的方法:
<Route component>
:在地址匹配的時(shí)候React的組件才會(huì)被渲染,route props也會(huì)隨著一起被渲染;
<Route render>
:這種方式對(duì)于內(nèi)聯(lián)渲染和包裝組件卻不引起意料之外的重新掛載特別方便;
<Route children>
:與render屬性的工作方式基本一樣,除了它是不管地址匹配與否都會(huì)被調(diào)用;
第一種方式?jīng)]啥可說(shuō)的,和之前一樣,這里我們重點(diǎn)看下 <Route render>
的渲染方式:
// 行內(nèi)渲染示例 <Route path="/home" render={() => <div>Home</div>}/> // 包裝/合成 const FadingRoute = ({ component: Component, ...rest }) => ( <Route {...rest} render={props => ( <FadeIn> <Component {...props}/> </FadeIn> )}/> ) <FadingRoute path="/cool" component={Something}/>
TIPS: 第三坑! <Route component>
的優(yōu)先級(jí)要比 <Route render>
高,所以不要在同一個(gè) <Route>
中同時(shí)使用這兩個(gè)屬性。
和之前版本沒(méi)太大區(qū)別,重點(diǎn)看下組件屬性:
to(string/object):要跳轉(zhuǎn)的路徑或地址;
replace(bool): 為 true 時(shí) ,點(diǎn)擊鏈接后將使用新地址替換掉訪問(wèn)歷史記錄里面的原地址; 為 false 時(shí) ,點(diǎn)擊鏈接后將在原有訪問(wèn)歷史記錄的基礎(chǔ)上添加一個(gè)新的紀(jì)錄。 默認(rèn)為 false ;
示例如下:
// Link組件示例 // to為string <Link to="/about">關(guān)于</Link> // to為obj <Link to={{ pathname: '/courses', search: '?sort=name', hash: '#the-hash', state: { fromDashboard: true } }}/> // replace <Link to="/courses" replace />
<NavLink>
是 <Link>
的一個(gè)特定版本, 會(huì)在匹配上當(dāng)前 URL 的時(shí)候會(huì)給已經(jīng)渲染的元素添加樣式參數(shù),組件屬性:
activeClassName(string):設(shè)置選中樣式,默認(rèn)值為 active;
activeStyle(object):當(dāng)元素被選中時(shí), 為此元素添加樣式;
exact(bool):為 true 時(shí), 只有當(dāng)?shù)刂吠耆ヅ?class 和 style 才會(huì)應(yīng)用;
strict(bool):為 true 時(shí),在確定位置是否與當(dāng)前 URL 匹配時(shí),將考慮位置 pathname 后的斜線; isActive(func):判斷鏈接是否激活的額外邏輯的功能;
從這里我們也可以看出,新版本的路由在組件化上面確實(shí)下了不少功夫,來(lái)看看NavLink的使用示例:
// activeClassName選中時(shí)樣式為selected <NavLink to="/faq" activeClassName="selected" >FAQs</NavLink> // 選中時(shí)樣式為activeStyle的樣式設(shè)置 <NavLink to="/faq" activeStyle={{ fontWeight: 'bold', color: 'red' }} >FAQs</NavLink> // 當(dāng)event id為奇數(shù)的時(shí)候,激活鏈接 const oddEvent = (match, location) => { if (!match) { return false } const eventID = parseInt(match.params.eventID) return !isNaN(eventID) && eventID % 2 === 1 } <NavLink to="/events/123" isActive={oddEvent} >Event 123</NavLink>
該組件用來(lái)渲染匹配地址的第一個(gè) <Route>
或者 <Redirect>
。那么它與使用一堆route又有什么區(qū)別呢?
<Switch>
的獨(dú)特之處是獨(dú)它僅僅渲染一個(gè)路由。相反地,每一個(gè)包含匹配地址(location)的 <Route>
都會(huì)被渲染。思考下面的代碼:
<Route path="/about" component={About}/> <Route path="/:user" component={User}/> <Route component={NoMatch}/>
如果現(xiàn)在的URL是 /about
,那么 <About>
, <User>
, 還有 <NoMatch>
都會(huì)被渲染,因?yàn)樗鼈兌寂c路徑(path)匹配。這種設(shè)計(jì),允許我們以多種方式將多個(gè) <Route>
組合到我們的應(yīng)用程序中,例如側(cè)欄(sidebars),面包屑(breadcrumbs),bootstrap tabs等等。 然而,偶爾我們只想選擇一個(gè) <Route>
來(lái)渲染。如果我們現(xiàn)在處于 /about
,我們也不希望匹配 /:user
(或者顯示我們的 “404” 頁(yè)面 )。以下是使用 Switch 的方法來(lái)實(shí)現(xiàn):
<Switch> <Route exact path="/" component={Home}/> <Route path="/about" component={About}/> <Route path="/:user" component={User}/> <Route component={NoMatch}/> </Switch>
現(xiàn)在,如果我們處于 /about
, <Switch>
將開始尋找匹配的 <Route>
。 <Route path="/about"/>
將被匹配, <Switch>
將停止尋找匹配并渲染 <About>
。同樣,如果我們處于 /michael
, <User>
將被渲染。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。