上一個項目用的還是 2.6.1,轉眼的功夫 4.0 都發佈了,API 變化實在有點大,2.X那套東西不頂用了,老老實實重新看一遍文檔,其中有幾點需要註意的,拿出來說一說。 本文只討論針對瀏覽器的應用,使用 react-router-dom(在react-router基礎上封裝了一些高級組件)進行說明 ...
上一個項目用的還是 2.6.1,轉眼的功夫 4.0 都發佈了,API 變化實在有點大,2.X那套東西不頂用了,老老實實重新看一遍文檔,其中有幾點需要註意的,拿出來說一說。
本文只討論針對瀏覽器的應用,使用 react-router-dom(在react-router基礎上封裝了一些高級組件)進行說明。
- 關於BrowserRouter:
如果按照原來的使用方式,就掉進第一個坑裡了:history不合法。
用 react-router-dom 中的 <HashRouter>組件代替原來的 <Router> 組件就可以了。
這是之前2.X版本處理瀏覽器路由的方式,4.0版本中推薦另一個組件:<BrowserRouter >
換上<BrowserRouter >之後會出現 2 個問題:
如果你不是通過伺服器啟動應用,因為chrome自身的安全機制,在本地環境下根本不能用chrome玩。這個不關鍵,我本地測試換個瀏覽器還不行麽,本地起個伺服器也不麻煩。
關鍵問題,刷新就是404。原因很簡單,BrowserRouter 和 HashRouter 完全不同,前者利用H5的 history 介面,前臺路由就是後臺收到的路由,你點到其他頁面一刷新,得,根本沒這個文件,伺服器也很無辜,到底讓我渲染個啥?後臺也可以簡單的解決這個問題:甭管你請求的啥地址,我先把入口文件扔給你。node處理方式如下(需要express):
app.get('*',(request,response)=>{ response.sendFile(path.resolve(__dirname,'../index.html')) })
啟動node伺服器,通過本機伺服器訪問,完美解決上面兩個問題。
(<MemoryRouter> 和 <StaticRouter> 分別是非瀏覽器環境和伺服器端渲染用的,在此不做討論。)
- BrowserRouter 里可以存在各種標簽。
原來用慣了2.X的同志們,看到新文檔的例子可能會發現這個問題:Router裡邊不是只能有Route麽,怎麼什麼都有。是的,4.0中 Router 里可以存在各種標簽。
- 導航連接<NavLink>:
看名字就是導航用的,主要用途就是區分激活的狀態,激活時的樣式。之前揉柔在Link里的。
- 只渲染第一個匹配的組件<Switch>:
一個路由可能同時匹配多個路徑,在<Switch>中,只渲染匹配的第一個,其他的放棄。之前這是Router的預設行為,4.0中為什麼不預設了呢?答:可以將多個Route組合到頁面中。想一想,如果你就是想同時渲染多個組件而不只是第一個呢?很欣慰看到我在2.X中吐槽的問題得到瞭解決。4.0版本給我最大的感覺就是:他讓瀏覽器更靈活的去渲染頁面。
- <Route>的渲染方法:
<Route component>
<Route render>
<Route children>
component和之前2.X的方法相同。
render可以傳個函數避免創建新的React element(內聯渲染時使用避免不必要的重載)。
children使用方式與render一致,只不過無論路由是否匹配都會被渲染。
exact屬性為 true 則需要路由完全匹配時才渲染組件(之前也是預設行為)。
- 三個重要對象:history,location,match
在 Route component 中,以 this.props.location 的方式獲取,
在 Route render 中,以 ({ location }) => () 的方式獲取,
在 Route children 中,以 ({ location }) => () 的方式獲取,
History 和 match的獲取方式類似。