React 生命周期转载自:https://www.jianshu.com/p/2c85958371af
组件生命周期分为三部分
组件创建阶段:组件生命周期函数一辈子只执行一次
- componentWillMount:组件将要被挂载,此时还没有开始渲染虚拟 DOM(现在已经更名为UNSAFE_componentWillMount,相对于 Vue 中的 created)
- render:第一次开始渲染真正的虚拟 DOM,当 render 执行完,内存中就有完整的虚拟 DOM 了
- componentDidMount:组件完成挂载,此时,组件已经显示到页面上了,当这个方法执行完,组件就都进入了运行中的状态(相对于 Vue 中的mounted)
组件运行阶段:根据组件 state 跟 props 的改变,有选择性的触发0次或者多次
- componentWillReceiveProps:组件将要接收新属性,此时,只要这个方法被触发,就证明父组件为当前子组件传递了新的属性值(首次并不会触发函数)
- shouldComponentUpdate:组件是否需要被更新,此时,组件尚未被更新,但是,state 和 props 肯定是最新的
- componentWillUpdate:组件将要被更新,此时,尚未开始更新,内存中的虚拟 DOM 树还是旧的,页面上的 DOM 树也是旧的
- componentDidUpdate:此时页面又被重新渲染了, state和虚拟 DOM和页面已经完成保持同步
- render:此时,又要重新根据最新的 state 和 props 重新渲染一颗内存中的虚拟 DOM 树,当 render 调用完毕,内存中的旧 DOM 树,已经被新 DOM 树替换了,此时页面还是旧的
组件销毁阶段:一辈子只执行一次- componentWillUnmount:组件将要被卸载,此时组件还可以正常使用
image
设置组件初始化默认值在 React 中,使用静态的 defaultProps 属性来设置组件的默认值
static defaultProps = {} 类型校验注意:如果需要为传递过来的属性做类型校验,在 v.15.*之后需要安装cnpm i prop-types,因为官方把类型校验模块在v.15.*之后单独抽离了出来
import ResctPropTypes from 'prop-types'
[JavaScript] 纯文本查看 复制代码 static propTypes = {
default: ResctPropTypes.number
} 例子: [JavaScript] 纯文本查看 复制代码 // @/components/propType
import React from 'react'
import ResctPropTypes from 'prop-types'
export default class PropType extends React.Component {
constructor(porps) {
super(porps)
this.state = {
default: porps.default
}
}
static defaultProps = {
default: 2
}
// 类型校验
static propTypes = {
default: ResctPropTypes.number
}
fun = {
click: () => {
this.setState({
default: this.state.default + 1
})
}
}
// 组件将要被挂载
componentWillMount() {
console.log('created')
}
// 第一次开始渲染真正的虚拟 DOM,当 render 执行完,内存中就有完整的虚拟 DOM 了
render() {
// 每当调用 render() 函数时,页面中的 DOM 还是旧的
console.log(this.refs.div && this.refs.div.innerHTML) // 运行中是才会打印 this.refs.div.innerHTML
return <div id="div" ref="div">
<button id="btn" onClick={this.fun.click}>+1</button><br/>
默认值是:{this.state.default}
<hr/>
<Son value={this.state.default}></Son>
</div>
}
// 执行完 componentDidMount 组件就进入了运行中的状态
componentDidMount() {
console.log('mounted', this.fun)
}
// ------------------ 下面是运行中的生命周期 -----------
// 组件是否需要被更新,此时,组件尚未被更新,但是,state 和 props 肯定是最新的,
// 注意:在 shouldComponentUpdate 中要求返回一个布尔值,
// 返回 false 不会触发下面的 shouldComponentUpdate 后面的生命周期,而是退回了运行中的状态
// 但是组件组件 state 中的值已经是被修改的了
shouldComponentUpdate(nextProps, nextState) {
// 下面做一个示例,展示 shouldComponentUpdate 中 this.state 中的值是怎么样的
// 示例是 偶数更新视图,基数不更新视图 0 2 4
// 发现了 this.state.default 并不是最新,是上一次的旧数据,那么我们可以通过 shouldComponentUpdate 的形参来获取最新的值
console.log("this.state.default:", this.state.default,"---","nextState:", nextState)
// this.state.default: 0 --- nextState: {default: 1}
// return this.state.default % 2 === 0 ?true:false
// return nextState.default % 2 === 0 ?true:false
return true
}
// 组件将要被更新,此时,尚未开始更新,内存中的虚拟 DOM 树还是旧的,页面上的 DOM 树也是旧的
componentWillUpdate(nextProps, nextState) {
// 经过打印,发现页面上的 DOM 节点 和 state 都是旧的,需要慎重操作,因为你可能操作的是旧的 DOM.
// console.log(document.querySelector('#div').innerHTML,'---this.state:',this.state)
// Vue 中的 $refs 跟 React 的 refs 差一个 $
console.log(this.refs.div.innerHTML, '---this.state:', this.state, '----nextState:', nextState)
// <button id="btn">+1</button><br>默认值是:0<hr><div><p>子组件</p>0</div> ---this.state: {default: 0} ----nextState: {default: 1}
}
// 组件完成了更新,虚拟 DOM 和 页面上的 DOM 和 state 都是最新的
componentDidUpdate(prevProps, prevState) { // 因为 props 跟 state 都是最新的了,componentDidUpdate 函数提供了 上一次的 props(prevProps) 和 上一次的 state(prevState)
console.log('最新的数据:', this.refs.div.innerHTML, '---this.state:',this.state)
// 最新的数据: <button id="btn">+1</button><br>默认值是:1<hr><div><p>子组件</p>1</div> ---this.state: {default: 1}
}
}
// 子组件
class Son extends React.Component {
constructor(props) {
super(props)
this.state = {
}
}
render() {
return <div>
<p>子组件</p>
{this.props.value}
</div>
}
// 组件将要接收新属性,此时,只要这个方法被触发,就证明父组件为当前子组件传递了新的属性值(首次并不会触发函数)
componentWillReceiveProps(nextProps) {
// 发现 this.props 不是最新的,是上一次的值
console.log("触发了 componentWillReceiveProps", '子组件的props值:',this.props.value, '--- nextProps:',nextProps.value)
// 触发了 componentWillReceiveProps 子组件的props值: 0 --- nextProps: 1
}
}
// 父组件
<PropType default={0}></PropType>
|