1)路由组件文件
import React,{ Component } from "react";
export default class Main extends Component {
constructor(props) {
super(props);
console.log("Main 执行构造函数!!!!");
}
getUserId = ()=> {
let {
match: {
params:{id}
}
} = this.props
return id
}
componentDidMount() {
let userId = this.getUserId()
console.log('挂载完成===',userId)
}
componentDidUpdate() {
let userId = this.getUserId()
console.log('更新完成===',userId)
}
render() {
console.log('render')
let userId = this.getUserId()
return (
<div>
<div>页面{userId}数据</div>
</div>
)
}
}
2)App组件文件
import React,{ Component } from "react";
import { Link,Route,Switch,Redirect } from "react-router-dom";
import "./App.css";
import Main from "./components/Main";
export default class App extends Component {
state = {count:0}
handleRender = ()=> {
console.log('将要render父组件')
this.setState({
count: this.state + 1
})
}
render(){
console.log('App 执行render。。。')
return (
<div className="app">
app....
<div>
<button onClick={this.handleRender}>执行父组件render</button>
</div>
<Link to="/mylist/userA"> 展示用户A</Link>
<Link to="/mylist/userB"> 展示用户B</Link>
{/* component直接》注册路由表 */}
<Route path="/mylist/:id" component={Main}/>
{/* component 》回调函数注册路由表 */}
{/* <Route path="/mylist/:id" component={(props)=>{
return(
// <Main key={props.match.params.id} {...props}/>
<Main {...props}/>
)
}}/> */}
{/* <Route path="/mylist/:id" render={(props)=>{
return(
// <Main key={props.match.params.id} {...props}/>
<Main {...props}/>
)
}}/> */}
<Redirect to="/mylist/userA"/>
</div>
)
}
}
结果:
-
(1)
component直接注册路由表:<Route path="/mylist/:id" component={Main}/>-
在点击路由切换的时候,只触发【组件的更新】,没有触发组件的【挂载完成】,可以知道触发了【组件的更新】
-
这种方式在
App组件render方法再执行时,不会造成Main组件重新渲染,只是update,缺点:不能从父组件传递props到子组件,可以在子组件访问路由属性。
-
-
(2)
component使用return组件来注册路由表:-
第一种情况,路由组件没有使用属性
key:<Route path="/mylist/:id" component={(props)=>{ return( <Main {...props}/> ) }}/>-
在点击路由切换的时候,只触发【组件的更新】,没有触发组件的【挂载完成】,可以知道触发了【组件的更新】,
props参数是路由组件的路由信息 -
这种方式会造成每次
App组件重新render时候Main组件都会重新执行一次初始化生命周期,而不是执行update,,但是它能够传递入参作为Main的props,可以访问路由属性,但是需要在函数指定入参,然后标记传递到子组件
-
-
第二种情况,路由组件使用了属性
key:<Route path="/mylist/:id" component={(props)=>{ return( <Main key={props.match.params.id} {...props}/> ) }}/>-
在点击路由切换的时候,只触发【挂载完成】,没有触发组件的【组件的更新】,可以知道触发了【组件的挂载】,
props参数是路由组件的路由信息 -
当
App组件render触发时,结果和不带属性key是一样的
-
-
第三种情况,路由组件不带任何参数
定义一个路由组件Test
import React,{ Component } from "react"; export default class Test extends Component { constructor(props) { super(props); console.log("Test 执行构造函数!!!!"); } componentDidMount() { console.log('Test》挂载完成') } componentDidUpdate(precProp) { console.log('Test》更新完成') } render() { return ( <div> <div>Test组件</div> </div> ) } }App组件文件核心代码如下:
<Route path="/mylist/:id" component={(props)=>{ return( <Test/> ) }}/>-
在点击路由切换的时候,只触发【组件的更新】,没有触发组件的【挂载完成】,可以知道触发了【组件的更新】,
props参数是路由组件的路由信息 -
当
App组件render触发时,结果和不带属性key是一样的
-
-
-
(3)
Route标签里直接写路由组件Test<Route path="/mylist/:id"> <Test/> </Route>- 点击路由,不触发钩子函数
- 这种方式每次(第一次除外)
App执行render不会造成Main重新执行一次初始化生命周期,只会执行update的生命钩子,可以从父组件传递props到子组件,但是这个方式有一个缺点,子组件不能在props访问路由属性
-
(4)
render方法<Route path="/mylist/:id" render={(props)=>{ return( // <Main key={props.match.params.id} {...props}/> <Main {...props}/> ) }}/>-
路由组件不带key属性:
-
在点击路由切换的时候,只触发【组件的更新】,没有触发组件的【挂载完成】,可以知道触发了【组件的更新】,
props参数是路由组件的路由信息 -
这种方式每次(第一次除外)
App执行render不会造成Main重新执行一次初始化生命周期,只会执行update的生命钩子,可以从父组件传递props到子组件,但是这个方式有一个缺点,子组件不能在props访问路由属性
-
-
路由组件带key属性:
- 在点击路由切换的时候,触发【挂载完成】【路由组件的构造函数】,没有触发组件的【组件的更新】,可以知道触发了【挂载完成】,
props参数是路由组件的路由信息
- 在点击路由切换的时候,触发【挂载完成】【路由组件的构造函数】,没有触发组件的【组件的更新】,可以知道触发了【挂载完成】,
-
当
App组件render触发时,结果和不带属性key是一样的
-