5、參數
DEMO位址
參考 4.params.js
React路由取參數,有兩種:
-
:這種屬于 search 字元串,在?a=1
裡取值;location.search
-
:這種需要從/a/123
裡取值;match.params
但無論哪種,路由擷取到的值,是跳轉後的那一刻的值,而不是實時更新的最新值。
具體來說:
- 假如 Link 标簽跳轉路徑實時綁定輸入框的一個值(假如值是
),這個值作為參數傳遞;abc
- 點選跳轉後,子元件讀取到目前傳的值
;abc
- 此時修改【1】中輸入框的值為
;def
- 請問子元件讀取到的值此時是多少?
還是abc
;def
- 答案是
;abc
- 原因是目前路徑是
,這個值讀取到的是目前路徑的值,而不是将要跳轉的路徑的值,是以不是實時更新的(顯然,也不應該是實時更新的);abc
手動修改位址欄的 url:
- 假如手動修改 url 為
,那麼請問讀取到的值是多少?ggg
- 我還真去試了一下。答案是除非你修改後,按回車跳轉路徑,會讀取到最新的;
- 否則,依然保持為修改前
;abc
- 即使你重新觸發 render 方法(比如修改 state 來實作),依然擷取到的是
,而不是abc
;ggg
擷取最新值:
- 如果你想要擷取到新值,那麼請重新點選跳轉(綁定了新的 url 的 Link 标簽)即可;
- 重新跳轉後(假如跳轉到同一個頁面),url 改變了,那麼元件會重新加載麼?
- 答案是否定的,如果跳轉到同一個元件,僅是參數改變,那麼元件是不會重新加載的,即元件内的資料保持之前不變,隻有傳遞的參數改變了(生命周期函數也不會重新執行);
比較特殊的,有關生命周期:
- 元件的生命周期函數,隻會在第一次挂載的時候執行,如果前後跳轉是同一個元件,那麼該元件的生命周期函數不會重複執行;
- 但 state 的生命周期,會多次執行(隻要父元件的 state 改變了,子元件的相關函數會被執行);
- 由于路由資訊是通過 props 傳值的,是以也會多次觸發;
- 不過沒有影響,傳的值依然是舊值(因為路由資訊沒變);
- 但假如你在 state 生命周期函數裡做了一些什麼事情,可能需要注意一下會不會帶來不良影響(雖然一般不會);
示例:
【例行引入和子元件】
import React from "react";
import {HashRouter as Router, Link, Route} from 'react-router-dom'
const First = props => <div>
第一個元件讀取參數(location.search) {props.location.search}
</div>
const Second = props => <div>
第二個元件讀取參數(match.params.myParams) {props.match.params.myParams}
</div>
【父元件,負責配置路由和傳值】
class RoutingNested extends React.Component {
constructor() {
super()
this.state = {
firstNumber: ,
secondNumber:
}
this.changeFirst = this.changeFirst.bind(this)
this.changeSecond = this.changeSecond.bind(this)
}
render() {
return <div>
<h3>、React-router 傳參</h3>
<h3>請在對應的跳轉标簽裡,輸入你想要傳的值</h3>
<Router>
<div>
<li>
<Link to={`${this.props.match.url}/?a=${this.state.firstNumber}`}
onClick={() => {
console.log('Link 标簽(跳轉到/1)的 onClick 事件', this.props.location)
}}>
示例
</Link>
<input type="text" value={this.state.firstNumber} onChange={this.changeFirst}/>
</li>
<li>
<Link to={`${this.props.match.url}//${this.state.secondNumber}`}
onClick={() => {
console.log('Link 标簽(跳轉到/2)的 onClick 事件', this.props.location)
}}>
示例
</Link>
<input type="text" value={this.state.secondNumber} onChange={this.changeSecond}/>
</li>
<hr/>
<Route path={`${this.props.match.url}/`} component={First}/>
<Route path={`${this.props.match.url}//:myParams`} component={Second}/>
</div>
</Router>
</div>
}
changeFirst(e) {
this.setState({
firstNumber: e.target.value
})
}
changeSecond(e) {
this.setState({
secondNumber: e.target.value
})
}
}