组件生命周期
一、理解
- 组件从创建到死亡它会经历一些特定的阶段。
- React组件中包含一系列勾子函数(生命周期回调函数), 会在特定的时刻调用。
- 我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作。
二、.生命周期流程图(旧)
三、生命周期的三个阶段(旧)
1. 初始化阶段: 由ReactDOM.render()触发—初次渲染
- constructor()
- componentWillMount()
- render()
- componentDidMount()
2. 更新阶段: 由组件内部this.setSate()或父组件重新render触发
- shouldComponentUpdate()
- componentWillUpdate()
- render()
- componentDidUpdate()
3. 卸载组件: 由ReactDOM.unmountComponentAtNode()触发
- componentWillUnmount()
四、分别对三个周期做代码演示和说明?
1.卸载组件
下面通过一个小案例引出组件的挂载和卸载时间点,以及对应的函数的书写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="test"></div>
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
class Life extends React.Component{
state={opacity:1}
death=()=>
{
ReactDOM.unmountComponentAtNode(document.getElementById("test"));
}
componentWillUnmount()
{
clearInterval(this.time);
}
componentDidMount()
{
this.time=setInterval(()=>
{
let{opacity}=this.state;
opacity-=0.1
if(opacity<0) opacity=1
this.setState({opacity:opacity})
},200);
}
render()
{
return (
<div>
<h1 style={{opacity:this.state.opacity}}>学会了React</h1>
<button onClick={this.death}> 点我取消</button>
</div>
)
}
}
ReactDOM.render(<Life/>,document.getElementById("test"));
</script>
</body>
说明:
由ReactDOM.unmountComponentAtNode()触发 componentWillUnmount()函数
2.挂载组件
挂载流程:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="test"></div>
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
class Life extends React.Component{
state={opacity:1}
constructor(props)
{
super(props);
console.log("constructor");
}
death=()=>
{
ReactDOM.unmountComponentAtNode(document.getElementById("test"));
}
componentWillUnmount()
{
console.log("componentWillUnmount")
clearInterval(this.time);
}
componentWillMount()
{
console.log("componentWillMount")
}
componentDidMount()
{
console.log("componentDidMount");
this.time=setInterval(()=>
{
let{opacity}=this.state;
opacity-=0.1
if(opacity<0) opacity=1
this.setState({opacity:opacity})
},200);
}
render()
{
console.log("render")
return (
<div>
<h1 style={{opacity:this.state.opacity}}>学会了React</h1>
<button onClick={this.death}> 点我取消</button>
</div>
)
}
}
ReactDOM.render(<Life/>,document.getElementById("test"));
</script>
</body>
3.setState更新组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="test"></div>
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
class Life extends React.Component{
state={opacity:1}
constructor(props)
{
super(props);
console.log("constructor");
}
death=()=>
{
ReactDOM.unmountComponentAtNode(document.getElementById("test"));
}
componentWillUnmount()
{
console.log("componentWillUnmount")
clearInterval(this.time);
}
componentWillMount()
{
console.log("componentWillMount")
}
shouldComponentUpdate()
{
console.log("shouldComponentUpdate")
return true;
}
componentWillUpdate()
{
console.log("componentWillUpdate")
}
componentDidUpdate()
{
console.log("componentDidUpdate")
}
componentDidMount()
{
console.log("componentDidMount");
this.time=setInterval(()=>
{
let{opacity}=this.state;
opacity-=0.1
if(opacity<0) opacity=1
this.setState({opacity:opacity})
},200);
}
render()
{
console.log("render")
return (
<div>
<h1 style={{opacity:this.state.opacity}}>学会了React</h1>
<button onClick={this.death}> 点我取消</button>
</div>
)
}
}
ReactDOM.render(<Life/>,document.getElementById("test"));
</script>
</body>
4.forceUpdate更新组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="test"></div>
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
class Life extends React.Component{
state={opacity:1}
constructor(props)
{
super(props);
console.log("constructor");
}
death=()=>
{
ReactDOM.unmountComponentAtNode(document.getElementById("test"));
}
componentWillMount()
{
console.log("componentWillMount")
}
shouldComponentUpdate()
{
console.log("shouldComponentUpdate")
return true;
}
componentWillUpdate()
{
console.log("componentWillUpdate")
}
componentDidUpdate()
{
console.log("componentDidUpdate")
}
render()
{
console.log("render")
return (
<div>
<h1 style={{opacity:this.state.opacity}}>学会了React</h1>
<button onClick={this.death}> 点我取消</button>
<button onClick={this.force}> 点我强制更新</button>
</div>
)
}
force=()=>
{
this.forceUpdate();
}
}
ReactDOM.render(<Life/>,document.getElementById("test"));
</script>
</body>
5.父组件带动子组件render
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="test"></div>
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
class LifeParent extends React.Component{
state={time:1}
flush=()=>
{
this.setState({time:2});
}
render()
{
return (
<div>
<h1>LifeParent</h1>
<button onClick={this.flush}>父类带动子类刷新</button>
<Life/>
</div>
)
}
}
class Life extends React.Component{
state={opacity:1}
constructor(props)
{
super(props);
console.log("constructor")
}
death=()=>
{
ReactDOM.unmountComponentAtNode(document.getElementById("test"));
}
componentWillMount()
{
console.log("componentWillMount")
}
componentWillReceiveProps()
{
console.log("componentWillReceiveProps")
}
shouldComponentUpdate()
{
console.log("shouldComponentUpdate")
return true;
}
componentWillUpdate()
{
console.log("componentWillUpdate")
}
componentDidUpdate()
{
console.log("componentDidUpdate")
}
componentDidMount()
{
console.log("componentDidMount")
}
render()
{
console.log("render")
return (
<div>
<h1 style={{opacity:this.state.opacity}}>学会了React</h1>
<button onClick={this.death}> 点我取消</button>
<button onClick={this.force}> 点我强制更新</button>
</div>
)
}
force=()=>
{
this.forceUpdate();
}
}
ReactDOM.render(<LifeParent/>,document.getElementById("test"));
</script>
</body>
五、生命周期流程图(新)
新和旧生命周期的区别: 废弃了“三”,迎来了“二”,为了以后的渲染做准g备,这三要在前面加上UNSAFE_ 引入新版本,用之前的代码,会发现会有提示
六、生命周期的三个阶段(新)
初始化阶段: 由ReactDOM.render()触发—初次渲染
1. constructor()
2. getDerivedStateFromProps
3. render()
4. componentDidMount()
更新阶段: 由组件内部this.setSate()或父组件重新render触发
1.getDerivedStateFromProps
2. shouldComponentUpdate()
3. render()
4. getSnapshotBeforeUpdate
5. componentDidUpdate()
卸载组件:
由ReactDOM.unmountComponentAtNode()触发componentWillUnmount()
重要的勾子
1.render:初始化渲染或更新渲染调用
2.componentDidMount:开启监听, 发送ajax请求
3.componentWillUnmount:做一些收尾工作, 如: 清理定时器
即将废弃的勾子
1.componentWillMount
2.componentWillReceiveProps
3.componentWillUpdate
现在使用会出现警告,下一个大版本需要加上UNSAFE_前缀才能使用,以后可能会被彻底废弃,不建议使用。
七、新生命周期的新的两个函数(不常用)
1.getDerivedStateFromProps
(没有太多意义)
返回null,组件可以更新 返回和state对象一样的对象,那么以后state对应的属性就更新不了 opcacity更新了,time更新不了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="test"></div>
<script src="../js/新版本/react.development.js"></script>
<script src="../js/新版本/react-dom.development.js"></script>
<script src="../js/新版本/babel.min.js"></script>
<script src="../js/新版本/prop-types.js"></script>
<script type="text/babel">
class Life extends React.Component{
state={opacity:1,time:1}
constructor(props)
{
super(props);
console.log("constructor");
}
static getDerivedStateFromProps()
{
console.log("getDrivedStateFromProps");
return {opacity:0.5};
}
render()
{
console.log("render")
return (
<div>
<h1 style={{opacity:this.state.opacity}}>学会了React</h1>
<h1>{this.state.time}</h1>
<button onClick={this.change}>点我变化第一行变化</button>
<button onClick={this.change1}>点我改变time</button>
</div>
)
}
change1=()=>
{
let {time}=this.state;
time-=0.1;
if(time<0) time=1
this.setState({time})
}
componentDidMount()
{
console.log("componentDidMount");
}
change=()=>{
let {opacity}=this.state;
opacity-=0.1;
if(opacity<0) opacity=1
this.setState({opacity})
}
}
ReactDOM.render(<Life/>,document.getElementById("test"));
</script>
</body>
</html>
可以接受props和state值,而且会将return回去的值与state进行拼接覆盖
2.getSnapshotBeforeUpdate
需要和componentDidUpdate一起使用 要return 更新后的调用函数 componentDidUpdate接受的两个参数, componentDidUpdate还可以再接受getSnapshotBeforeUpdate return回来的参数
总结
上述就是生命周期的函数调用过程
|