網站首頁 編程語言 正文
React路由參數改變頁面不刷新數據的情況
路由的參數由于是在componentDidMount中獲取的,如果在詳情頁面再次打開詳情頁面,由于組件并沒有重新渲染,導致didMount不會獲取路由參數。
因此在參數改變的時候,可以利用componentWillReceiveProps來更新變量。
// 獲取路由參數 componentDidMount() { const didMountId = this.props.location.query.id; this.setState({ id: didMountId }, () => { this.props.pageList({ id: this.state.id }); // 請求接口獲取數據 }); } //組件更新時被調用 componentWillReceiveProps(newProps) { if (newProps.location.query.id !== this.state.id) { this.setState({ id: newProps.location.query.id}, () => { this.props.pageList({ id: this.state.id}); //當路由參數改變時,重新請求接口獲取數據 }); } }
React頁面路由
前端路由和后端路由
在web開發早期的年代里,前端的功能遠不如現在這么強大,一直是后端路由占據主導地位。服務端渲染就是在瀏覽器請求頁面URL時,(每次切換頁面時,瀏覽器都會刷新頁面)服務端按照不同的URL地址與不同的html + css + 后端數據 之間的映射,直接將我們需要的HTML文本組裝好,并返回給瀏覽器,這個HTML文本被瀏覽器解析之后,不需要經過JavaScript腳本的執行,可直接構建出完整的DOM樹并展示頁面中。
前端路由介紹
隨著 ajax 的使用越來越廣泛,前端的頁面邏輯開始變得越來越復雜,特別是單頁Web應用(Single Page Web Application,SPA))的興起,前端路由系統隨之開始流行。
1、用戶的角度
前端路由主要實現了兩個功能(使用ajax更新頁面狀態的情況下):
記錄當前頁面的狀態(保存或分享當前頁的url,再次打開該url時,網頁還是保存(分享)時的狀態);
可以使用瀏覽器的前進后退功能(如點擊后退按鈕,可以使頁面回到使用ajax更新頁面之前的狀態,url也回到之前的狀態);
2、作為開發者
要實現這兩個功能,我們需要做到:
改變url且不讓瀏覽器向服務器發出請求;
監測 url 的變化;
截獲 url 地址,并解析出需要的信息來匹配路由規則。
匹配模式
模糊匹配模式
- 默認情況下, React路由是模糊匹配模式
- 模糊匹配規則:只要pathname以path開頭就會匹配成功,對應的組件就會被渲染出來。
精確匹配
- 給 Route組件添加exact屬性,讓其變為精確匹配模式
- 精確匹配:只有當path和 pathname完全匹配時才會展示該路由,嚴格匹配不要隨便開啟,需要再開,有些時候開啟會導致無法繼續匹配二級路由。
路由的執行過程
- 點擊Link組件(a標簽)會修改瀏覽器地址欄中的url
- React路由監聽到地址欄url的變化。
- Reat路由內部遍歷所有 Route組件,使用路由規則(path)與 pathname進行匹配。
- 當路由規則(path)能夠匹配地址欄中的pathname時,就展示渲染該 Route組件的內容
hash模式
這里的 hash 就是指 url 尾巴后的 # 號以及后面的字符。這里的 # 和 css 里的 # 是一個意思。hash也稱作錨點,本身是用來做頁面定位的,她可以使對應 id 的元素顯示在可視區域內。
由于 hash 值變化不會導致瀏覽器向服務器發出請求,而且 hash 改變會觸發 hashchange 事件,瀏覽器的進后退也能對其進行控制,所以人們在 html5 的 history 出現前,基本都是使用 hash 來實現前端路由的。
window.location.hash = 'qq' // 設置 url 的 hash,會在當前url后加上 '#qq' var hash = window.location.hash // '#qq' window.addEventListener('hashchange', function(){ ? ? // 監聽hash變化,點擊瀏覽器的前進后退會觸發 })
history模式
已經有 hash 模式了,而且 hash 能兼容到IE8, history 只能兼容到 IE10,為什么還要搞個 history 呢?
首先,hash 本來是拿來做頁面定位的,如果拿來做路由的話,原來的錨點功能就不能用了。
其次,hash 的傳參是基于 url的,如果要傳遞復雜的數據,會有體積的限制,而history 模式不僅可以在url里放參數,還可以將數據存放在一個特定的對象中。
? ?window.history.pushState(state, title, url) // state:需要保存的數據,這個數據在觸發popstate事件時,可以在event.state里獲取 // title:標題,基本沒用,一般傳 null // url:設定新的歷史記錄的 url。新的 url 與當前 url 的 origin 必須是一樣的,否則會拋出錯誤。url可以是絕對路徑,也可以是相對路徑。
window.history.replaceState(state, title, url) // 與 pushState 基本相同,但她是修改當前歷史記錄,而 pushState 是創建新的歷史記錄 window.addEventListener("popstate", function() { ? ? // 監聽瀏覽器前進后退事件,pushState 與 replaceState 方法不會觸發 }); window.history.back() // 后退 window.history.forward() // 前進 window.history.go(1) // 前進一步,-2為后退兩步,window.history.length可以查看當前歷史堆棧中頁面的數量
react-router-dom API
React實現頁面路由的模塊:react-router-dom
1、HashRouter和BrowserRouter
其實就是路由的hash和history兩種模式,并且這兩個組件是路由的容器,必須在最外層。
// hash模式 ReactDOM.render( ?? ? <HashRouter> ? ? ? ?? ?<Route path="/" component={Home}/> </HashRouter> )
// history模式 ReactDOM.render( ?? ? ? <BrowserRouter> ? ? ? ?? ? <Route path="/" component={Home} /> ? ? ? </BrowserRouter> )
2、Route
路由的一個原材料,它是控制路徑對應顯示的組件。 Route的參數:
-
path
:跳轉的路徑 -
component
: 對應路徑顯示的組件 -
render
:可以自己寫render函數返回具體的dom,而不需要去設置component。 -
location
: 傳遞route對象,和當前的route對象對比,如果匹配則跳轉 -
exact
: 匹配規則,true的時候則精確匹配。
3、Link和NavLink
(1)Link的api
to: 有兩種寫法,表示跳轉到哪個路由
字符串寫法
<Link to="/a" ? />
對象寫法
? <Link to={{ ? pathname: '/courses', ? search: '?sort=name', ? hash: '#the-hash', ? state: { fromDashboard: true } }}/>
-
replace
:就是將push改成replace -
innerRef
:訪問Link標簽的dom
(2) NavLink的api
- Link的所有api
- activeClassName 路由激活的時候設置的類名
- activeStyle 路由激活設置的樣式
- exact 參考Route,符合這個條件才會激活active類
- strict 參考Route,符合這個條件才會激活active類
- isActive 接收一個回調函數,active狀態變化的時候回觸發,返回false則中斷跳轉。
const oddEvent = (match, location) => { ? console.log(match,location) ? if (!match) { ? ? return false ? } ? console.log(match.id) ? return true } <NavLink isActive={oddEvent} to="/a/123">組件一</NavLink>
- location 接收一個location對象,當url滿足這個對象的條件才會跳轉。
<NavLink to="/a/123" location={{ key:"mb5wu3", pathname:"/a/123" }}/>
4、Redirect:頁面重定向
// 基本的重定向 <Redirect to="/somewhere/else" /> // 對象形式 <Redirect ? to={{ ? ? pathname: "/login", ? ? search: "?utm=your+face", ? ? state: { referrer: currentLocation } ? }} /> // 采用push生成新的記錄 <Redirect push to="/somewhere/else" /> // 配合Switch組件使用,form表示重定向之前的路徑,如果匹配則重定向,不匹配則不重定向 <Switch> ? <Redirect from='/old-path' to='/new-path'/> ? <Route path='/new-path' component={Place}/> </Switch>
5、Switch
路由切換,只會匹配第一個路由,可以想象成tab欄
Switch內部只能包含Route、Redirect、Router
?<Switch> ? <Route exact path="/" component={Home}/> ? <Route path="/about" component={About}/> ? <Route path="/:user" component={User}/> ? <Route component={NoMatch}/> </Switch>
6、Router Hooks
在Router5.x中新增加了Router Hooks用于在函數組件中獲取路由信息。使用規則和React的其他Hooks一致。
-
useHistory
:返回history對象 -
useLocation
:返回location對象 -
useRouteMatch
:返回match對象 -
useParams
:返回match對象中的params,也就是path傳遞的參數
? ?import React from ‘react'; ? ? import { useHistory } from ‘react-router-dom'; ?function backBtn(props) { ? ? ? ? let ?history = useHistory; ? ? ? ? return <button onClick={ ()=> { ? ? ? ? ? ? ? history.goBack(); }>返回上一頁</button> ? ? ? ?}
7、history對象
在每個路由組件中我們可以使用this.props.history獲取到history對象,也可以使用withRouter包裹組件獲取,在history中封裝了push,replace,go等方法,具體內容如下:
History { ? ? length: number; ? ? action: Action; ? ? location: Location; ? ? push(path: Path, state?: LocationState): void; // 調用push前進到一個地址,可以接受一個state對象,就是自定義的路由數據 ? ? push(location: LocationDescriptorObject): void; // 接受一個location的描述對象 ? ? replace(path: Path, state?: LocationState): void; // 用頁面替換當前的路徑,不可再goBack ? ? replace(location: LocationDescriptorObject): void; // 同上 ? ? go(n: number): void; // 往前走多少也頁面 ? ? goBack(): void; // 返回一個頁面 ? ? goForward(): void; // 前進一個頁面 ? ? block(prompt?: boolean | string | TransitionPromptHook): UnregisterCallback; ? ? listen(listener: LocationListener): UnregisterCallback; ? ? createHref(location: LocationDescriptorObject): Href; }
這樣我們想使用api來操作前進后退就可以調用history中的方法?
原文鏈接:https://blog.csdn.net/qq_44877496/article/details/107745066
相關推薦
- 2022-08-25 C語言詳細分析結構體的內存對齊規則_C 語言
- 2023-03-19 Android全面屏適配與判斷超詳細講解_Android
- 2022-12-10 C++?vector與數組轉換寫入/讀出文件方式_C 語言
- 2022-10-05 matplotlib之Pyplot模塊繪制三維散點圖使用顏色表示數值大小_python
- 2023-03-23 Pandas分組聚合之使用自定義函數方法transform()、apply()_python
- 2022-12-23 C++?Boost?Exception超詳細講解_C 語言
- 2023-04-20 el-table多選+搜索
- 2022-03-16 Linux系統中日志詳細介紹_Linux
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支