React基础性总结(一):组件的生命周期及执行顺序
“ 关注
前端开发社区,回复
"1"即可加入
前端技术交流群,回复
"2"即可免费领取 500G前端干货!
作者:前端林子 https://cloud.tencent.com/developer/article
关注‘前端开发社区’每天精选好文
本文作为React总结系列的第一篇文章,会总结组件的生命周期及执行顺序,涉及内容比较基础。在后面的系列文章中则会总结React Hooks等内容。
1.七个可选的生命周期
说明:
- componentWillMount()
仅在render()方法前被调用一次,如果在该方法中调用了setState方法去改变组件的状态值,那么调用render()后,将会直接看到改变过了的状态值,并且不论状态值怎么改变,componentWillMount()都不会再被调用。
- componentDidMount()
仅在render()方法后被立即调用一次,相对于父组件而言,该方法在子组件中会先被调用。如果需要使用一些JaveScript框架或者类似于setInterval()这样的方法,建议在该方法内使用。
- shouldComponentUpdate(object nextProps, object nextState)
在首次渲染调用
render()方法时不会被调用,后面在接受到新的state或者props时,在render()方法前被调用。为防止一些潜在的bug,该方法默认总是返回true。如果确定state及props改变后不需要渲染组件,那么也可以指定返回false,需要注意的是,这样的结果会导致后面的render()、componentWillUpdate()、componentDidUpdate()都不会被调用。不过,React官方建议这个方法仅用来做
优化性能,不要用这个方法来阻止渲染,因为可能会产生bug。
例如React内置的PureComponent的类,当我们的组件继承于它时,组件更新时就会默认先比较新旧属性和状态,从而决定组件是否更新。值得注意的是,PureComponent进行的是
浅比较,所以组件状态或属性改变时,都需要返回一个新的对象或数组
- componentWillReceiveProps(object nextProps)
在初始渲染调用render()方法时不会被调用,当接收到一个
新的props时,该方法被调用。另外,如果改变一个状态的值,则会触发render()方法。因此可以在这个方法里调用setState()方法去改变一个状态的值,当该方法接收到新的props时,setState()就可以避免一次额外的render()了。
- componentWillUpdate(object nextProps, object nextState)
在初始渲染调用render()方法时不会被调用,当接收到新的props及state时,在render()方法之前被调用。
不要在此方法再去更新
props或者
state
- componentDidUpdate(object prevProps, object prevState)
在初始渲染调用render()方法时不会被调用,当组件更新被刷新到DOM之后被立即调用。
可以在这里访问,并
修改 DOM
- componentWillUnmount()
在组件从DOM上卸载前被调用,在这个方法里面,主要是完成一些清除操作,比如说清除掉一些过时了的定时器等。
2.执行顺序
-
getDefaultProps(),调用1次
-
getInitialState(),调用1次
-
componentWillMount(),调用1次
-
render(),调用>=1次
-
componentDidMount():调用1次
-
componentWillReceiveProps(object nextProps),调用>=0次
-
ShouldComponentUpdate(object nextProps, object nextState),调用>=0次
-
componentWillUpdate(object nextProps, object nextState),调用>=0次
-
render(),调用>=1次
-
componentDidUpdate(object prevProps, object prevState),调用>=0次
-
componentWillUnmount(),调用1次
3.实例
<!DOCTYPE html> <html> <head> <script src="https://fb.me/react-15.2.0.js"></script> <script src="https://fb.me/react-dom-15.2.0.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script> </head> <body> <div id="app-container"></div> <script type="text/babel"> var SubCounter = React.createClass({ componentWillReceiveProps:function() { console.log('9、子组件将要接收到新属性'); }, shouldComponentUpdate:function(newProps, newState) { console.log('10、子组件是否需要更新'); if (newProps.number < 5) return true; return false }, componentWillUpdate:function() { console.log('11、子组件将要更新'); }, componentDidUpdate:function() { console.log('13、子组件更新完成'); }, componentWillUnmount:function() { console.log('14、子组件将卸载'); }, render:function() { console.log('12、子组件挂载中'); return ( <p>{this.props.number}</p> ) } }); var Counter = React.createClass({ getInitialState:function(){ return( this.state={ number:0 } ) }, componentWillMount:function(){ console.log('3、父组件挂载之前'); }, componentDidMount:function(){ console.log('5、父组件挂载完成'); }, shouldComponentUpdate:function(newProps, newState) { console.log('6、父组件是否需要更新'); if (newState.number<15) return true; return false }, componentWillUpdate:function() { console.log('7、父组件将要更新'); }, componentDidUpdate:function() { console.log('8、父组件更新完成'); }, handleClick : function(){ this.setState({ number: this.state.number + 1 }) }, render:function() { console.log('4、render(父组件挂载)'); return ( <div> <p>{this.state.number}</p> <button onClick={this.handleClick}>+</button> {this.state.number<10?<SubCounter number={this.state.number}/>:null} </div> ) } }); ReactDOM.render(<Counter />, document.getElementById('app-container')); </script> </body> </html>
结果:
4. 其他
- constructor(props){}
constructor(props){ super(props); this.state = {} }
在React组件挂载之前,会调用它的构造函数。在为 React.Component 子类实现构造函数时,应先调用 super(),并传入参数props。构造函数中,可以通过this.state来初始化组件内部的state(注意这里不是setState()方法来设置state),还可以为事件处理函数绑定实例:
constructor(props) { super(props); // 注意:不要在这里调用 this.setState() this.state = { counter: 0 }; this.handleClick = this.handleClick.bind(this); }
- defaultProps
用于为class组件添加默认的props,示例:
class sayHello extends React.Component { render() { return ( <h1>Hello,{this.props.name}</h1> ); } } sayHello.defaultProps = { name:"Peter" }
- propTypes 进行类型检测
PropTypes 提供一系列验证器,可用于确保组件接收到的prop值是有效的。当传入的 prop 值类型不正确时,JavaScript 控制台将会显示警告。示例:
import PropTypes from 'prop-types'; class sayHello extends React.Component { render() { return ( <h1>Hello,{this.props.name}</h1> ); } } sayHello.propTypes = { name: PropTypes.string };
- render()
对于一个组件而言,render()方法是必须的,通常在这个方法里面都会返回一个元素(如:
<div></div>),但同样也可以返回false或null,这意味着没有任何东西需要渲染。
如有问题,欢迎指正,如有侵权请联系小编删除~~
往期:
请各位帅哥美女多多支持帅编,回复
“1”即可加入前端技术交流群,回复
"2"即可领取 500G 前端干货
- Vue的学习总结自测(三)—— vue生命周期、Vue 的父组件和子组件生命周期钩子函数执行顺序、生命周期内调用异步请求
- React组件的生命周期及执行顺序
- React组件生命周期-初始化阶段的函数执行顺序
- React子父组件生命周期函数执行顺序
- React组件生命周期-正确执行初始化阶段的函数
- React组件生命周期-正确执行运行阶段的函数
- 附实例!图解React的生命周期及执行顺序
- 【React】 12课 react的生命周期函数执行顺序详解
- React总结2:React组件生命周期
- 附实例!图解React的生命周期及执行顺序
- 深入理解Vue父子组件生命周期执行顺序及钩子函数
- 【Vue】零基础学习Vue: 第21课 Vue父子组件生命周期函数的执行顺序:
- React 组件的生命周期总结
- Vue父子组件生命周期执行顺序及钩子函数的个人理解
- React组件生命周期总结
- VUE生命周期中的钩子函数及父子组件的执行顺序
- React 生命周期函数执行顺序
- Vue.js嵌套组件生命周期执行顺序
- jmeter(1) 组件执行顺序
- ASP.NET MVC 生命周期/事件执行顺序