react生命周期图解~~~
*************************************分割线************************************
import React, { Component } from 'react'
class UserList extends Component {
// constructor是ES6对类的默认方法,通过 new 命令生成对象实例时自动调用该方法。并且,该方法是类中必须有的,
// 如果没有显示定义,则会默认添加空的constructor( )方法。
constructor(props) {
// 子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,
// 必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,
// 加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。
super(props)
console.log('constructor')
// *****当你使用使用普通函数,必须把函数this指向到 UserList (不推荐使用这个方法)
// this.handleClick = this.handleClick.bind(this)
// 在这里设置数据,在其他地方调用该数据使用 this.state.time
this.state = {
name: 'Mark',
Number: 1,
time: '20190105 090522'
}
}
// *****handleClick普通函数写法 (不推荐使用这个方法)
// handleClick() {
// this.setState({ name: 'Zuck' })
// }
// handleClick 箭头函数写法,不用在 constructor(props) 里去指向this (推荐使用这个方法)
handleClick = () => {
// 修改数据,使用 this.setState() 方法
this.setState({ name: 'Zuck' })
}
// 盗墓笔记测试接口 axios
allList = () => {
let data = `盗墓笔记`
this.$http.post(`/novelSearchApi?name=${data}`).then(res => {
console.log(res)
})
}
// **挂载前**
// 组件初始化时只调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state。
componentWillMount() {
console.log('componentWillMount')
let time = this.$moment(this.state.time).format('YYYY-MM-DD HH:mm:ss')
console.log(time)
}
// **挂载后**
// 组件渲染之后调用,只调用一次。
// 一般在这里更新数据,调用接口
componentDidMount() {
console.log('componentDidMount')
this.allList()
}
// **更新前**
// 组件初始化时不调用,只有在组件将要更新时才调用,此时可以修改state
componentWillUpdate(nextProps, nextState) {
// console.log(nextProps,nextState)
console.log('componentWillUpdate')
}
// **更新后**
// 组件初始化时不调用,组件更新完成后调用,此时可以获取dom节点。
componentDidUpdate() {
console.log('componentDidUpdate')
}
// **销毁前**
// 组件将要卸载时调用,一些事件监听和定时器需要在此时清除。
componentWillUnmount() {
console.log('componentWillUnmount')
}
// **判断组件是否应该重新渲染,默认是true**
// react性能优化非常重要的一环。组件接受新的state或者props时调用,我们可以设置在此对比前后两个props和state是否相同,
// 如果相同则返回false阻止更新,因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,
// 节省大量性能,尤其是在dom结构复杂的时候
// shouldComponentUpdate函数是重渲染时render()函数调用前被调用的函数,它接受两个参数:nextProps和nextState,
// 分别表示下一个props和下一个state的值。并且,当函数返回false时候,阻止接下来的render()函数的调用,阻止组件重渲染,而返回true时,组件照常重渲染。
shouldComponentUpdate(nextProps, nextState) {
// console.log(nextProps,nextState)
console.log('shouldComponentUpdate')
// 在render函数调用前判断:如果前后state中name不变,通过return false阻止render调用
if (nextState.name === this.state.name) {
return false
} else {
return true
}
}
// 组件初始化时不调用,组件接受新的props时调用。
componentWillReceiveProps() {
console.log('componentWillReceiveProps')
}
// react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行。此时就不能更改state了。
render() {
return (
<div>
List
<div onClick={this.handleClick}>Hi, {this.state.name}</div>
</div>
)
}
}
export default UserList
1、通常我在componentWillMount发送ajax(渲染dom之前做的操作)
2、componentDidMount也可以做ajax操作(渲染dom完成之后做的操作)
那么,这2种情况如何区分呢?
需求1:
当你的render函数需要有数据才能渲染的时候,就在componentWillMount做操作。
render() {
return data && <div>{data}</div>
}
需求2:
当你的render不需要数据,先渲染dom结构,就在componentDidMount操作。
render() {
const { data } = this.props
return (
<div>
<span>我要先渲染</span>
<span>{data || ''}</span>
</div>
)
}