React 从入门到进阶之路(九)
之前的文章我们介绍了 React propTypes defaultProps。接下来我们将介绍 React 生命周期函数。
之前我们已经根据 create-react-app 模块创建了一个 React 项目,并定义 App.js 为根组件,即父组件,Home.js 为子组件。我们看一下两个组件的代码:
App.js
1 import React, {Component} from 'react'; 2 import Home from './components/Home'; 3 4 class App extends Component { 5 constructor(props) { 6 super(props); 7 this.state = { 8 title: "我是父组件 App 的 title", 9 flag: true, 10 } 11 } 12 13 setFlag = () => { 14 this.setState({ 15 flag: !this.state.flag 16 }) 17 } 18 19 setTitle = () => { 20 this.setState({ 21 title: "我是父组件 App 更改后的 title" 22 }) 23 } 24 25 render() { 26 return ( 27 <div className="App"> 28 { 29 this.state.flag ? <Home title={this.state.title}/> : "" 30 } 31 32 <hr/> 33 {/*通过 flag 来控制子组件 Home 的挂载与销毁*/} 34 <button onClick={this.setFlag}>控制Home组件挂载销毁</button> 35 36 <hr/> 37 {/*通过 flag 来控制子组件 Home 的挂载与销毁*/} 38 <button onClick={this.setTitle}>修改App组件的title值</button> 39 40 </div> 41 ); 42 } 43 } 44 45 export default App;
Home.js
1 import React, {Component} from 'react'; 2 3 class Home extends Component { 4 constructor(props) { 5 console.log('01构造函数'); 6 super(props); 7 this.state = { 8 name: '我是子组件 Home 的 name', 9 sex: 1 10 }; 11 } 12 13 //组件将要挂载的时候触发的生命周期函数 14 componentWillMount() { 15 console.log('02组件将要挂载'); 16 } 17 18 //组件挂载完成的时候触发的生命周期函数 19 componentDidMount() { 20 //dom操作放在这个里面,请求数据也放在这个里面 21 console.log('04组件挂载完成'); 22 } 23 24 //是否要更新数据 如果返回true才会执行更新数据的操作 25 shouldComponentUpdate(nextProps, nextState) { 26 console.log('01是否要更新数据'); 27 // 父组件传递过来的更改后的值 28 console.log(nextProps); 29 // 子组件更改后 this.state 的值 30 console.log(nextState); 31 // 如果为 true 则可以更新数据,如果为 false 则不能更新数据 32 return true; 33 } 34 35 //将要更新数据的时候触发 36 componentWillUpdate() { 37 console.log('02组件将要更新'); 38 } 39 40 //组件更新完成 41 componentDidUpdate() { 42 console.log('04组件数据更新完成'); 43 } 44 45 //在父组件里面改变props传值的时候触发的 46 componentWillReceiveProps() { 47 console.log('父子组件传值,父组件里面改变了props的值触发的方法') 48 } 49 50 setName = () => { 51 this.setState({ 52 name: '我是子组件 Home 更改后的 name 值' 53 }) 54 } 55 56 //组件销毁的时候触发的生命周期函数,用在组件销毁的时候执行操作 57 componentWillUnmount() { 58 console.log('组件销毁了'); 59 } 60 61 render() { 62 console.log('03数据渲染render'); 63 return ( 64 <div> 65 {/*父组件 App 传递过来的 title 值*/} 66 <p>{this.props.title}</p> 67 68 <br/><br/> 69 {/*更改子组件 Home 的 name 值*/} 70 <button onClick={this.setName}>更新name的数据</button> 71 </div> 72 ); 73 } 74 } 75 76 export default Home;
我们在父组件 App 中通过 <Home /> 标签插入子组件 Home,将 this.state 中的 title 值传给 Home 组件,并通过一个 flag 属性来控制该 Home 组件的挂载和销毁,并在 App 组件中顶一个一个 setTitle 的方法可以改变 this.state 中 title 的值。
我们在子组件 Home 中定义了很多组件的生命周期函数,下面我们来一点点分析。
我们先来看当页面加载时浏览器端的显示:
从控制台的输出结果我们可以看出组件在挂在时经历了四个阶段:
1、constructor:组件在挂载前最先经历该阶段,初始化数据。
2、componentWillMount,组件将要挂载时触发的生命周期函数。
3、render:数据渲染 render
4、componentDidMount:组件挂载完成时触发的生命周期函数。我们可以将 DOM 操作和请求数据放在这里面。
当我们点击 更新name的数据 的 button 按钮时,将 this.state 中的 name 值进行更改,浏览器的显示如下:
从控制台的输出结果我们可以看出组件在挂在时经历了四个阶段:
1、shouldComponentUpdate:是否需要更新数据,在该生命周期函数中如果 return true,则表示可以更新数据,如果 return false,则表示不允许更新数据,当更新数据时是不成功的。同时该生命周期函数中有两个传参 nextProps,nextState,其中 nextProps 表示父组件传递过来的值更改后的值,这个我们在下面的例子中解释。nextState 表示子组件更改后子组件中 this.state 的数据,从控制台的打印结果可以看出 this.state 中 name 值已经变成了更改后的值。
2、componentWillUpdate,将要更新数据的时候触发的生命周期函数。
3、render:数据渲染 render
4、componentDidUpdate:组件更新完成时触发的生命周期函数。
当我们点击 修改App组件的title值 的 button 按钮时,该 button 是父组件 App 的的一个按钮,将 App 组件中 this.state 的 title 值进行更改,浏览器的显示如下:
从控制台的输出结果我们可以看出组件在挂在时经历了五个阶段:
1、shouldWillReceiveProps:在父组件里面改变 props 传值的时候触发。
2、shouldComponentUpdate:是否需要更新数据,在该生命周期函数中如果 return true,则表示可以更新数据,如果 return false,则表示不允许更新数据,当更新数据时是不成功的。同时该生命周期函数中有两个传参 nextProps,nextState,其中 nextProps 表示父组件传递过来的值更改后的值,从控制台的打印结果可以看出 App 组件 this.state 中 title 值已经变成了更改后的值。nextState 表示子组件更改后子组件中 this.state 的数据,。
3、componentWillUpdate,将要更新数据的时候触发的生命周期函数。
4、render:数据渲染 render
5、componentDidUpdate:组件更新完成时触发的生命周期函数。
当我们点击 控制Home组件挂载销毁 的 button 按钮时,该 button 是父组件 App 的的一个按钮,当 App 组件的 this.state 中 flag 为 true 时 Home 组件挂载,当 flag 为 false 时 Home 组件销毁,浏览器的显示如下:
从控制台的输出结果我们可以看出组件在挂在时经历了一个阶段:
1、shouldWillUnmount:组件销毁的时候触发的生命周期函数。
当我们再次点击 控制Home组件挂载销毁 的 button 按钮时,组件又重新挂载,就会再在执行组件挂载时的生命周期函数,最后效果如下: