流程图
组件创建阶段
static defaultProps
外界没有传入props参数的时候,不会出错。
this.state
在调用构造器的时候就会被调用
componentWillMount
组件的虚拟DOM元素,将要挂载到页面上的时候执行,此时,虚拟DOM还没被创建
render
开始渲染虚拟DOM,当render执行完,虚拟DOM才在内存中创建好
但是此时虚拟DOM并没有挂载到页面上
componentDidMount
表示组件已经挂载,此时的我们的state上的数据 和内存中的虚拟DOM以及
浏览器重的页面,已经保持一致了,组件创建阶段的生命周期函数,执行完毕。
页面第一被渲染好,(一般在这里面可以进行dom节点的操作了)。
执行特点:
只执行一次
组件运行阶段
如果state或者props发生了改变就会出发相应的钩子。
如果属性props改变执行componentWillReceiveProps,
当外界传递给子组件的属性被修改了会触发。
组件接收新属性,此时,只要这个方法触发,就证明父组件为当前子组件传递了新的属性值。
之后触发shouldComponentUpdate(组件是否更新),
如果是则进行如下步骤:
componentWillUpdate(组件将要被更新,还没更新)
->render(重新渲染内存中的DOM对象,此时的DOM树和state已经保持一致了,
但是页面还是旧的)->componentDidUpdate(更新页面)
执行特点:
依据props或state,选择性触发0次或者多次。
组件卸载阶段
componentWillUnmount
组件尚可被使用 还没被卸载。
执行特点:
只执行一次
代码示例
import React from "react";
import ReactTypes from "prop-types"
export default class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
msg: "ok",
count: props.initCount
}
}
//设置组件的默认属性值
static defaultProps = {initCount: 0}
//在这个静态对象里可以做类型校验
//需要第三方包prop-types
static propTypes = {
initCount: ReactTypes.number
}
handleClick = () => {
this.setState({
count: this.state.count + 1
})
}
myselfFunction() {
console.log("我定义了个函数")
}
//组件将要挂载的时候执行,此时虚拟DOM未创建
componentWillMount() {
// console.log(this.props.initCount)
console.log(this.state.msg)
console.log(this.myselfFunction())
}
render() {
//&&短路运算可以预防undefined引起的异常。
console.log("ref", this.refs.h3 && this.refs.h3.innerText)
return <div>
<h1>这是Counter计数器组件</h1>
<input type="button" value="+1" id="btn" onClick={() => this.handleClick()}/>
<hr/>
<h3 id="myh3" ref="h3">
当前的数量是:{this.state.count}
</h3>
</div>
}
componentDidMount() {
//在这里执行dom的操作
const h3text = document.getElementById("myh3")
// h3text.style.background="red"
// React中不推荐使用元生dom的方式创建click事件
// const btn = document.getElementById("btn")
// btn.onclick=()=>{
// this.setState({
// count:this.state.count+1
// })
// }
console.log("in componentDidMount", h3text)
}
//生命函数创建阶段结束
//生命周期执行阶段开始
shouldComponentUpdate(nextProps, nextState, nextContext) {
//只有return值为true的时候页面才发生变化。
//为false的时候只改变状态但是页面不更新。
let flag = false
console.log("before count", this.state.count)
//如果奇数true,偶数false
//页面显示的值比state少1。
//使用nextState拿最新的值,然后看到网页展示数字只有奇数
if (nextState.count & 0x1 === 1) {
flag = true
} else {
console.log("...")
}
console.log(`in shouldComponentUpdate return value is ${flag}`)
console.log("after count", nextState.count)
return flag
}
//分支:props改变才会触发
componentWillReceiveProps(nextProps, nextContext) {
//举例父组件向子组件传值,第一次的时候不会触发
console.log("in componentWillReceiveProps")
}
//此时虚拟DOM还是旧的内容
componentWillUpdate() {
console.log("in componentWillUpdate")
console.log("ref", this.refs.h3.innerText)
}
//接下来执行render重新渲染虚拟DOM
//此时页面的dom是最新的了
componentDidUpdate(prevProps, prevState, snapshot) {
console.log("当前", this.state.count)
}
}