React 路由傳參的幾種實現(xiàn)方法
引言
在上一篇中,我們學(xué)習(xí)了 React 中使用路由技術(shù),以及如何使用 MyNavLink 去優(yōu)化使用路由時的代碼冗余的情況。
這一節(jié)我們繼續(xù)上一篇 React 路由進行一些補充
1. Switch 解決相同路徑問題
首先我們看一段這樣的代碼
<Route path="/home" component={Home}></Route> <Route path="/about" component={About}></Route> <Route path="/about" component={About}></Route>
這是兩個路由組件,在2,3行中,我們同時使用了相同的路徑 /about
我們發(fā)現(xiàn)它出現(xiàn)了兩個 about 組件的內(nèi)容,那這是為什么呢?
其實是因為,Route 的機制,當匹配上了第一個 /about 組件后,它還會繼續(xù)向下匹配,因此會出現(xiàn)兩個 About 組件,這時我們可以采用 Switch 組件進行包裹
<Switch> <Route path="/home" component={Home}></Route> <Route path="/about" component={About}></Route> <Route path="/about" component={About}></Route> </Switch>
在使用 Switch 時,我們需要先從 react-router-dom 中暴露出 Switch 組件
這樣我們就能成功的解決掉這個問題了
2. 解決二級路由樣式丟失的問題
當我們將路徑改寫成 path="/ljc/about" 這樣的形式時,我們會發(fā)現(xiàn)當我們強制刷新頁面的時候,頁面的 CSS 樣式消失了。這是因為,我們在引入樣式文件時,采取的是相對路徑,當我們使用二級路由的時候,會使得請求的路徑發(fā)生改變,瀏覽器會向 localhost:3000/ljc 下請求 css 樣式資源,這并不是我們想要的,因為我們的樣式存放于公共文件下的 CSS 文件夾中。
我們有幾種方法,可以解決這個問題
- 將樣式引入的路徑改成絕對路徑
- 引入樣式文件時不帶 .
- 使用 HashRouter
我們一般采用第一種方式去解決
3. 路由的精準匹配和模糊匹配
路由的匹配有兩種形式,一種是精準匹配一種是模糊匹配,React 中默認開啟的是模糊匹配
模糊匹配可以理解為,在匹配路由時,只要有匹配到的就好了
精準匹配就是,兩者必須相同
我們展示一個模糊匹配的例子
<MyNavLink to = "/home/a/b" >Home</MyNavLink>
這個標簽匹配的路由,我們可以拆分成 home a b,將會根據(jù)這個先后順序匹配路由
<Route path="/home"component={Home}/>
就可以匹配到上面的這個路由,因為它匹配的是 home
當匹配的路由改成下面這樣時,就會失敗。它會按照第一個來匹配,如果第一個沒有匹配上,那就會失敗,這里的 a 和 home 沒有匹配上,很顯然會失敗
<Route path="/a" component={Home}/>
當我們開啟了精準匹配后,就我們的第一種匹配就不會成功,因為精準匹配需要的是完全一樣的值,開啟精準匹配采用的是 exact 來實現(xiàn)
<Route exact={true} path="/home" component={Home}/>
4. 重定向路由
在我們寫好了這些之后,我們會發(fā)現(xiàn),我們需要點擊任意一個按鈕,才會去匹配一個組件,這并不是我們想要的,我們想要頁面一加載上來,默認的就能匹配到一個組件。
這個時候我們就需要時候 Redirecrt 進行默認匹配了。
<Redirect to="/home" />
當我們加上這條語句時,頁面找不到指定路徑時,就會重定向到 /home 頁面下因此當我們請求3000端口時,就會重定向到 /home 這樣就能夠?qū)崿F(xiàn)我們想要的效果了
5. 嵌套路由
嵌套路由也就是我們前面有提及的二級路由,但是嵌套路由包括了二級、三級...還有很多級路由,當我們需要在一個路由組件中添加兩個組件,一個是頭部,一個是內(nèi)容區(qū)
我們將我們的嵌套內(nèi)容寫在相應(yīng)的組件里面,這個是在 Home 組件的 return 內(nèi)容
<div> <h2>Home組件內(nèi)容</h2> <div> <ul className="nav nav-tabs"> <li> <MyNavLink className="list-group-item" to="/home/news">News</MyNavLink> </li> <li> <MyNavLink className="list-group-item " to="/home/message">Message</MyNavLink> </li> </ul> {/* 注冊路由 */} <Switch> <Route path="/home/news" component={News} /> <Route path="/home/message" component={Message} /> </Switch> </div> </div>
在這里我們需要使用嵌套路由的方式,才能完成匹配
首先我們得 React 中路由得注冊是有順序得,我們在匹配得時候,因為 Home 組件是先注冊得,因此在匹配的時候先去找 home 路由,由于是模糊匹配,會成功的匹配
在 Home 組件里面去匹配相應(yīng)的路由,從而找到 /home/news 進行匹配,因此找到 News 組件,進行匹配渲染
如果開啟精確匹配的話,第一步的 /home/news 匹配 /home 就會卡住不動,這個時候就不會顯示有用的東西了!
6. 傳遞 params 參數(shù)
首先我們需要實現(xiàn)的效果是,點擊消息列表,展示出消息的詳細內(nèi)容
這個案例實現(xiàn)的方法有三種,第一種就是傳遞 params 參數(shù),由于我們所顯示的數(shù)據(jù)都是從數(shù)據(jù)集中取出來的,因此我們需要有數(shù)據(jù)的傳輸給 Detail 組件
我們首先需要將詳細內(nèi)容的數(shù)據(jù)列表,保存在 DetailData 中,將消息列表保存在 Message 的 state 中。
我們可以通過將數(shù)據(jù)拼接在路由地址末尾來實現(xiàn)數(shù)據(jù)的傳遞
<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>
如上,我們將消息列表的 id 和 title 寫在了路由地址后面
這里我們需要注意的是:需要采用模板字符串以及 $ 符的方式來進行數(shù)據(jù)的獲取
在注冊路由時,我們可以通過 :數(shù)據(jù)名 來接收數(shù)據(jù)
<Route path="/home/message/detail/:id/:title" component={Detail} />
如上,使用了 :id/:title 成功的接收了由 Link 傳遞過來的 id 和 title 數(shù)據(jù)
這樣我們既成功的實現(xiàn)了路由的跳轉(zhuǎn),又將需要獲取的數(shù)據(jù)傳遞給了 Detail 組件
我們在 Detail 組件中打印 this.props 來查看當前接收的數(shù)據(jù)情況
我們可以發(fā)現(xiàn),我們傳遞的數(shù)據(jù)被接收到了對象的 match 屬性下的 params 中
因此我們可以在 Detail 組件中獲取到又 Message 組件中傳遞來的 params 數(shù)據(jù)
并通過 params 數(shù)據(jù)中的 id 值,在詳細內(nèi)容的數(shù)據(jù)集中查找出指定 id 的詳細內(nèi)容
const { id, title } = this.props.match.params const findResult = DetailData.find((detailObj) => { return detailObj.id === id })
最后渲染數(shù)據(jù)即可
7. 傳遞 search 參數(shù)
我們還可以采用傳遞 search 參數(shù)的方法來實現(xiàn)
首先我們先確定數(shù)據(jù)傳輸?shù)姆绞?/p>
我們先在 Link 中采用 ? 符號的方式來表示后面的為可用數(shù)據(jù)
<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>
采用 search 傳遞的方式,無需在 Route 中再次聲明,可以在 Detail 組件中直接獲取到
我們可以發(fā)現(xiàn),我們的數(shù)據(jù)保存在了 location 對象下的 search 中,是一種字符串的形式保存的,我們可以引用一個庫來進行轉(zhuǎn)化 querystring
import qs from 'querystring'
這個庫是 React 中自帶有的,它有兩個方法,一個是 parse 一個是 stringify
我們可以采用 parse 方法,將字符串轉(zhuǎn)化為鍵值對形式的對象
const { search } = this.props.location const { id, title } = qs.parse(search.slice(1))
這樣我們就能成功的獲取數(shù)據(jù),并進行渲染
tips:無需聲明接收
8. 傳遞 state 參數(shù)
采用傳遞 state 參數(shù)的方法,是我覺得最完美的一種方法,因為它不會將數(shù)據(jù)攜帶到地址欄上,采用內(nèi)部的狀態(tài)來維護
<Link to={{ pathname: '/home/message/detail', state: { id: msgObj.id, title: msgObj.title } }}>{msgObj.title}</Link>
首先,我們需要在 Link 中注冊跳轉(zhuǎn)時,傳遞一個路由對象,包括一個 跳轉(zhuǎn)地址名,一個 state 數(shù)據(jù),這樣我們就可以在 Detail 組件中獲取到這個傳遞的 state 數(shù)據(jù)
注意:采用這種方式傳遞,無需聲明接收
我們可以在 Detail 組件中的 location 對象下的 state 中取出我們所傳遞的數(shù)據(jù)
const { id, title } = this.props.location.state
直接使用即可~
解決清除緩存造成報錯的問題,我們可以在獲取不到數(shù)據(jù)的時候用空對象來替代,例如,
const { id, title } = this.props.location.state || {}
當獲取不到 state 時,則用空對象代替
這里的 state 和狀態(tài)里的 state 有所不同
到此這篇關(guān)于React 路由傳參的幾種實現(xiàn)方法的文章就介紹到這了,更多相關(guān)React 路由傳參內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React onClick/onChange傳參(bind綁定)問題
這篇文章主要介紹了React onClick/onChange傳參(bind綁定)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02React Ant Design樹形表格的復(fù)雜增刪改操作
這篇文章主要介紹了React Ant Design樹形表格的復(fù)雜增刪改操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11react-redux action傳參及多個state處理的實現(xiàn)
本文主要介紹了react-redux action傳參及多個state處理的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07