1.初始化阶段
1.1 componentWillMount()
在render之前执行,在这个函数中可以进行渲染之前的最后一次 state 修改
import React, { Component } from "react";
export default class App extends Component {
state = {
text:"人生自古谁无死,留取丹心照汗青"
};
render() {
return <div>{this.state.text}</div>;
}
componentWillMount(){
this.setState({
text:"生亦何欢,死亦何苦,喜乐悲愁,皆归尘土"
})
}
}
1.2 render ()
只能访问 this.props 和 this.state ,不能进行状态的修改和DOM输出
import React, { Component } from "react";
export default class App extends Component {
state = {
text: "人生自古谁无死,留取丹心照汗青",
};
render() {
return (
<div>
<Child parentText={'小楼昨夜又东风,故国不堪回首月明中'}></Child>
</div>
);
}
componentWillMount() {
this.setState({
text: "生亦何欢,死亦何苦,喜乐悲愁,皆归尘土",
});
}
}
class Child extends Component {
state = {
text:"春花秋月何时了,往事知多少?",
errorText:''
};
render() {
return <div>
<p>{this.state.text}</p>
<p>{this.props.parentText}</p>
</div>;
}
}
1.2 componentDidMount()
执行 render() 函数之后并完成真实DOM的渲染之后触发,可以获取到DOM
import React, { Component } from "react";
export default class App extends Component {
render() {
return (
<div>
<p id="p_tag">问君能有几多愁?恰是一江春水向东流</p> </div>
);
}
componentDidMount(){
console.log(document.getElementById('p_tag').innerText)
}
}
1.4 componentWillReceiveProps()
父组件修改属性是触发
import React, { Component } from "react";
export default class App extends Component {
state = {
text: "人生自古谁无死,留取丹心照汗青",
};
render() {
return (
<div>
<p id="p_tag" onClick={()=>{
this.setState({
text:"小楼昨夜又东风,故国不堪回首月明中"
})
}}>问君能有几多愁?恰是一江春水向东流</p>
<Child parentText={this.state.text}></Child>
</div>
);
}
}
class Child extends Component {
state = {
text:"",
};
render() {
return <div>
<p>{this.state.text}</p>
</div>;
}
componentWillReceiveProps(nextProps){
console.log('nextProps',nextProps);
this.setState({
text:nextProps.parentText+"---李煜"
})
}
}
1.5 shouldComponentUpdate()
返回值决定是否进行render的调用,例如当点击tab切换需要进行展示数据切换,那么我们在多次点击同一个tab 时也会执行 setState() ,会执行 render 函数 ,但是我们的数据并没有变化,在数据没有改变的情况下,多次执行 render 函数,显然是不友好的,此时,我们就可以使用 shouldComponentUpdate 在做判断,是否需要执行render 函数,在shouldComponentUpdate()里面可以访问到 this.state 和 this.props ,并且接收两个形参,使我们可以访问到 nextPoprs 和 nextState ,(我觉得这个可以参考 VUE 的监听来做理解),在这个方法里面我们可以访问到 state 和 props 的新值和旧值 ,我们可以根据新值与旧值得对于来判断是否需要重新执行 render 函数
shouldComponentUpdate(nextProps,nextState){
return JSON.stringify(nextState)==JSON.stringify(nextState)
}
1.6 componentWillUpdate()
组件即将更新, 在render()函数钱执行,不能进行状态和属性的更改,可以拿到 nextProps 和 nextState
1.7 componentDidUpdate()
可以进行DOM的修改
1.8 componentWillUnmount()
组件即将被卸载,可以在这个函数里面清除定时器和事件监听,如果有熟悉 VUE 的小伙伴,可以参考VUE 的 beforeDestroy 来理解
import React, { Component } from "react";
export default class App extends Component {
state = {
isShow:true
};
render() {
return <div>
<button onClick={()=>{
this.setState({
isShow:false
})
}}>移除</button>
{this.state.isShow && <Child></Child>}
</div>;
}
}
class Child extends Component {
render() {
return <div>凭阑半日独无言,依旧竹声新月似当年</div>;
}
componentDidMount(){
window.onresize=()=>{
console.log(888);
}
}
componentWillUnmount(){
console.log('唉,我要被移除了');
window.onresize=null;
}
}
老生命周期存在的问题
componentWillMount
在 ssr 中会被多次调用,所以出触发多次,如果在这里进行事件绑定,将无法解绑,会造成内存泄漏,变得不够安全高效,逐步废弃.
componentWillReceiveProps
外部组件多次频繁的传入不同的props,会导致多次不必要的异步请求,逐步废弃
componentWillUpdate
更新前记录DOM的状态,可能会做一些处理,与componentDidUpdate 之间相隔时间如果过长,会导致状态不可信
新的生命周期
getDerivedStateFromProps
第一次初始化组件以及后续的更新过程(自身状态的更新和父组件引起的更新)会返回一个对象作为新的 state,如果返回 null 则说明不需要进行 state 的更新,在这里可以拿到 nextProps 和nextState,最新的 props 和 state, 这个方法是静态方法,静态方法的 this 指向这个类,而不是实例
import React, { Component } from "react";
export default class App extends Component {
state = {
name: "test",
};
render() {
return (
<div>
<button
onClick={() => {
this.setState({
name: "my love",
});
}}
>
change
</button>
<p>{this.state.name}</p>
<p>{this.state.sex}</p>
</div>
);
}
static getDerivedStateFromProps(nextProps, nextState) {
console.log(nextProps, nextState);
return {
name: nextState.name.toUpperCase(),
};
}
}
getSnapshotBeforeUpdate
取代了componentWillUpdate 函数,触发时间是 update 发生的时候,在 render 之后 DOM渲染之前 返回一个值,返回的这个值 作为 componentDidUpdate 的第三个参数
import React, { Component } from "react";
import "./css/02-案例选项卡.css";
export default class App extends Component {
state = {
list: [
1, 2, 34, 5, 6, 7, 78, 8, 9, 3, 4, 5, 5, 8942, 4234, 432, 43, 424, 533,
788, 534, 423, 534,
],
};
myref=React.createRef()
render() {
return (
<div className="snapshot_wrap">
<button
onClick={() => {
let newList = [];
for (let index = 0; index < 20; index++) {
newList.push(`花明月暗笼轻雾,今宵好向郎边去.刬袜步香阶,手提金缕鞋.${index + 1}`);
}
this.setState({
list: [...newList, ...this.state.list],
});
}}
>
添加邮件
</button>
<h1>邮箱应用</h1>
<ul id="box" ref={this.myref}>
{this.state.list.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
</div>
);
}
getSnapshotBeforeUpdate(){
return this.myref.current.scrollTop
}
componentDidUpdate(prevProps, prevState, snapshot){
console.log(snapshot,this.myref.current.scrollHeight);
this.myref.current.scrollTop+=this.myref.current.scrollHeight-snapshot
}
}
|