一,初始化
componentWillMount :render之前最后一次修改状态的机会
render :只能访问this.props 和 this.state ,不允许修改状态和DOM输出
componentDidMount :成功render并渲染完成真实的DOM之后触发,可以修改DOM
二,运行中
componentWillReceiveProps :父组件修改属性触发
shouldComponentUpdate: 返回false会阻止render调用
componentWillUpdate: 不能修改属性和状态
render:只能访问this.props和this.state ,不允许修改状态和DOM输出
componentDidUpdate :可以修改DOM
三,销毁
componentWillUnmount: 在删除组件之前进行清理操作,比如计时器和事件监听器
注意:
1.componentWillMount,在ssr中 ,这个方法将会被多次调用,所以会重复触发多遍, 同时在这里如果绑定事件,讲无法解绑 ,导致内存泄漏 , 变得不够安全高效, 逐步废弃 。
2.componentWillReceiveProps ,外部组件多次频繁更新传入多次不同的props,会导致不必要的异步请求
3.componentWillUpdate ,更新前记录DOM状态,可能会做一些处理, 与componentDidUpdate相隔时间如果过长 ,会导致状态不太新
解决(两个新的生命周期):
1.getDerivedStateFromProps, 第一次的初始化组件以及后续的更新过程中(包括自身状态更新以及父传子),返回一个对象作为新的State,返回null则说明不需要在这里更新state
2.getSnapshotBeforeUpdate ,取代了componentWillUpdate,触发时间为update发生的时候 ,在render之后 , dom渲染之前,返回一个值 , 作为componentDidUpdate的第三个参数 。
import React, { Component } from 'react'
import Axios from 'axios'
class App extends Component {
state = {
name: 'shirley',
datalist: []
}
componentDidMount() {
Axios.get('/test.json').then(res => {
console.log(res)
this.setState({
datalist: res.data
})
})
console.log('componentDidMount')
}
componentWillMount() {
console.log('componentWillMount')
}
render() {
var list = this.state.datalist.map(item =>
<li key={item.id}>{item.username}</li>
)
console.log('render')
return <div>
hello --{this.state.name}
<ul>
{list}
</ul>
</div>
}
}
export default App
shouldComponentUpdate(nextProps, nextState) {
console.log("shouldComponentUpdate")
if (this.state.name == nextState.name) {
return false
}
return true
}
import React, { Component } from 'react'
class App extends Component {
state = {
type: 1
}
render() {
console.log('render')
return <div>
app
<ul>
<li onClick={() => this.handleClick('1')}>衣服</li>
<li onClick={() => this.handleClick('2')} > 裤子</li>
<li onClick={() => this.handleClick('3')}> 鞋</li>
</ul>
child---{this.state.type}
<Child></Child>
</div>
}
handleClick(type) {
this.setState({
type: type
})
}
}
class Child extends Component {
render() {
return <div>
child
</div>
}
componentWillReceiveProps(nextProps) {
console.log('axios 发请求 带上参数' + nextProps.type)
}
}
export default App
class Child extends Component{
state = {
childtype:1
}
render(){
return <div>
child -{this.props.type}
</div>
}
componentDidMount() {
console.log("axios 发请求 带上参数"+this.props.type)
}
componentWillUnmount(){
console.log("componentWillUnmount","清除定时器,window.οnscrοll=null")
}
// UNSAFE_componentWillReceiveProps(nextProps){
// // console.log("componentWillReceiveProps","孩子组件中会执行",nextProps)
// console.log("axios 发请求 带上参数"+nextProps.type)
// }
static getDerivedStateFromProps(props, state) {
console.log(props)
return {
childtype:props.type
}
}
componentDidUpdate(prevProps, prevState) {
// console.log(this.state.childtype)
if(prevState.childtype === this.state.childtype){
return ;
}
console.log("axios 发请求 带上参数"+this.state.childtype)
}
}
getSnapshotBeforeUpdate = (prevProps, prevState) => {
console.log("getSnapshotBeforeUpdate","记录滚动条的位置或者轮播索引位置")
return {
top:document.documentElement.scrollTop
}
}
componentDidUpdate(prevprops,prevState,data){
console.log("componentDidUpdate")
document.documentElement.scrollTop = data.top
}
react中性能优化的方案
1.shouldComponentUpdate ,控指组件自身或者子组件是否需要更新,尤其在子组件非常多的情况下,需要进行优化
2.PureComponent ,会帮你比较 新props和旧的props, 新的state和老的state(值相等,或者对象含有相同的属性,且属性值相等),决定shouldComponentUpdate返回true或者false,从而决定要不要呼叫render function 。
注意,如果你的state和props永远都会变,那PureComponent并不会比较快,因为shallowEqual也需要时间