新版生命周期
-
componentWillMount:在渲染前调用。
-
componentDidMount:在第一次渲染后调用(发起Ajax请求)
-
componentWillReceiveProps:在组件接收到一个新的props时被调用。这个方法在第一次渲染时不会被调用。
-
shouldComponentUpdate:返回一个布尔值。在组件接收到新的props或state时被调用。在初始化时或者使用forceUpdate时不被调用。可以在你确认不需要更新组件时使用。
-
componentWillUpdate:在组件接收到新的props或state,但还没有render时被调用。在初始化时不会被调用。
-
componentDidUpdate:在组件完成更新后立即调用。在初始化时不会被调用。
-
componentWillUnmount 在组件从DOM中移除的时候立刻被调用。
import React from "react"
import ReactDOM from "react-dom"
class Counter extends React.Component{
static defaultProps = {name:"wangcai"} // 默认属性
constructor(props){
super(props)
this.state = {number:0}
}
UNSAFE_componentWillMount(){
console.log("Counter: componentWillMount")
}
shouldComponentUpdate(nextProps,nextState){
console.log("Counter: shouldComponentUpdate")
return true;
}
componentWillUpdate(){
console.log("Counter: componentWillUpdate")
}
componentDidUpdate(){
console.log("Counter: componentDidUpdate")
}
handleClick = ()=>{
this.setState({number:this.state.number+1})
}
render(){
console.log("Counter: render") // 2
return(
<div>
<h1>父组件</h1>
<p>{this.state.number}</p>
<button onClick={this.handleClick}>+</button>
<hr/>
{this.state.number%2==0 ? <SubCounter number={this.state.number}></SubCounter> : null}
</div>
)
}
componentDidMount(){
console.log("Counter: componentDidMount") // 3
}
}
class SubCounter extends React.Component{
UNSAFE_componentWillMount(){
console.log("SubCounter: componentWillMount") // 1
}
componentDidMount(){
console.log("SubCounter: componentDidMount") // 3
}
componentWillReceiveProps(){
console.log("SubCounter: componentWillReceiveProps")
}
shouldComponentUpdate(){
console.log("SubCounter: shouldComponentUpdate")
// return false;
return true;
}
componentWillUpdate(){
console.log("SubCounter: componentWillUpdate") //
}
componentDidUpdate(){
console.log("SubCounter: componentDidUpdate")
}
render(){
console.log("SubCounter: render")
return(
<div>
<h1>子组件</h1>
<p>{this.props.number}</p>
</div>
)
}
componentWillUnmount(){
console.log("SubCounter: componentWillUnmount")
}
}
ReactDOM.render(<Counter />, window.app)
新版生命周期
getDerivedStateFromProps:将接收的属性变成自身的状态,并且可以修改状态,是一个静态函数,所以函数体内不能访问this,简单说,就是应该一个纯函数,输出完全由输入决定。
import React from "react";
import ReactDOM from "react-dom";
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = { number: 0 };
}
handleClick = () => {
this.setState({ number: this.state.number + 1 });
};
render() {
return (
<div>
<h1>父组件</h1>
<p>{this.state.number}</p>
<button onClick={this.handleClick}>+</button>
<hr />
<SubCounter number={this.state.number}></SubCounter>
</div>
);
}
}
class SubCounter extends React.Component {
state = {
number: 0
};
static getDerivedStateFromProps(nextProps, prevState) {
// console.log("nextProps: ",nextProps) // {number: 0}
let { number } = nextProps;
return { number };
}
render() {
return (
<div>
<h1>子组件</h1>
<p>{this.state.number}</p>
</div>
);
}
}
ReactDOM.render(<Counter />, window.app);
getSnapshotBeforeUpdate:获取更新之前DOM的快照,getSnapshotBeforeUpdate中返回了一个值,这个值会给componedDidUpdate的最后一个参数
import React from "react"
import ReactDOM from "react-dom"
class News extends React.Component{
constructor(props){
super(props)
this.scrollRef = React.createRef();
}
state = {
news:[]
}
componentDidMount(){
this.timer = setInterval(()=>{
this.setState({
news:[`${this.state.news.length}`,...this.state.news]
})
},1000)
}
componentWillUnmount(){
clearInterval(this.timer)
}
// 获取更新之前dom的快照
getSnapshotBeforeUpdate(){
return this.scrollRef.current.scrollHeight;
}
componentDidUpdate(prevProps,prevState,lastScrollHeight){
let scrollTop = this.scrollRef.current.scrollTop;
this.scrollRef.current.scrollTop = scrollTop+(this.scrollRef.current.scrollHeight-lastScrollHeight)
}
render(){
let styles = {
height:"100px",
width:"200px",
border:"1px solid red",
overflow:"auto"
}
return(
<ul style={styles} ref={this.scrollRef}>
{
this.state.news.map((item,index)=><li key={index}>{item}</li>)
}
</ul>
)
}
}
ReactDOM.render(<News />, window.app)