React生命周期的新旧对比
一、介绍生命周期
需求:
1、文字从透明度为1变为0,反复执行这个动画
2、点击按钮将页面清空(卸载组件)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生命周期</title>
</head>
<body>
<!-- 创建一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- 引入bable,将jsx转化为js -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
class Demo extends React.Component {
state = {
opacity: 1 }
//卸载组件
death = () => {
ReactDOM.unmountComponentAtNode(document.querySelector('#test'))
}
//组件挂载完成
componentDidMount() {
this.timer = setInterval(() => {
let {
opacity } = this.state;
opacity -= 0.1;
if (opacity <= 0) opacity = 1;
this.setState({
opacity });
}, 200);
}
//组件将要卸载
componentWillUnmount() {
//清除定时器,否则会一直执行计时器
clearInterval(this.timer)
}
//组件渲染的时候,状态更新之后
render() {
console.log('render')
return (
<div>
<h2 style={
{
opacity: this.state.opacity }}>React?</h2>
<button onClick={
this.death}>卸载</button>
</div>
)
}
}
ReactDOM.render(<Demo />, document.querySelector('#test'))
</script>
</body>
</html>
二、生命周期(旧)
16x版本的生命周期顺序:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生命周期</title>
</head>
<body>
<!-- 创建一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- 引入bable,将jsx转化为js -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
class Demo extends React.Component {
constructor(props) {
console.log('最开始:constructor')
super(props)
this.state = {
Count: 0 }
}
//组件将要挂载
componentWillMount() {
console.log('组件将要挂载,componentWillMount')
}
//组件渲染的时候,状态更新之后
render() {
console.log('组件渲染的时候,状态更新之后:render')
const {
Count } = this.state;
return (
<div>
<h2>求和为{
Count}</h2>
<button onClick={
this.add}>加一</button>
<button onClick={
this.death}>卸载组件</button>
<button onClick={
this.force}>强制更新</button>
</div>
)
}
//组件挂载完成
componentDidMount() {
console.log('组件挂载完成:componentDidMount')
}
//控制组件更新的“阀门”(如果不写默认是true)
shouldComponentUpdate() {
console.log('控制组件更新的“阀门”:shouldComponentUpdate')
//返回值是true的才能继续往下一个生命周期走
return true
}
//组件将要更新
componentWillUpdate() {
console.log('组件将要更新:componentWillUpdate')
}
//组件更新完成
componentDidUpdate() {
console.log('组件更新完成:componentDidUpdate')
}
//组件将要卸载
componentWillUnmount() {
console.log('组件将要卸载:componentWillUnmount')
}
//卸载组件
death = () => {
ReactDOM.unmountComponentAtNode(document.querySelector('#test'))
}
//强制更新 - 不更改setState的数据
force = () => {
this.forceUpdate()
}
add = () => {
let {
Count } = this.state;
Count++;
this.setState({
Count })
}
}
ReactDOM.render(<Demo />, document.querySelector('#test'))
</script>
</body>
</html>
子父组件的生命周期(componentWillReceiveProps)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>生命周期(子父组件)</title>
</head>
<body>
<!-- 创建一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<!-- 引入bable,将jsx转化为js -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
//定义父组件
class Parent extends React.Component {
state = {
name: '奔驰' }
change = () => {
this.setState({
name: '宝马' })
}
render() {
console.log('父组件渲染的时候,状态更新之后:render')
return (
<div>
<div>parent</div>
<button onClick={
this.change}>切换</button>
<Child name={
this.state.name} />
</div>
)
}
}
//定义子组件
class Child extends React.Component {
//组件将要接收到Props
componentWillReceiveProps() {
console.log('子组件将要接收父组件的Props:componentWillReceiveProps')
}
//组件挂载完成
componentDidMount() {
console.log('子组件挂载完成:componentDidMount')
}
render() {
console.log('子组件渲染的时候,状态更新之后:render')
return (
<div>
<div>child:{
this.props.name}</div>
</div>
)
}
//控制组件更新的“阀门”(如果不写默认是true)
shouldComponentUpdate() {
console.log('控制子组件更新的“阀门”:shouldComponentUpdate')
//返回值是true的才能继续往下一个生命周期走
return true
}
//组件将要更新
componentWillUpdate() {
console.log('子组件将要更新:componentWillUpdate')
}
//组件更新完成
componentDidUpdate() {
console.log('子组件更新完成:componentDidUpdate')
}
//组件将要卸载
componentWillUnmount() {
console.log('子组件将要卸载:componentWillUnmount')
}
}
ReactDOM.render(<Parent />, document.querySelector('#test'))
</script>
</body>
</html>
三、生命周期(新)
17x版本的生命周期顺序:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>17版本生命周期</title>
</head>
<body>
<!-- 创建一个容器 -->
<div id="test"></div>
<!-- 引入react核心库 -->
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
<!-- 引入bable,将jsx转化为js -->
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
<script type="text/babel">
/* 新的生命周期和旧的生命周期相比,它废弃了3个钩子:componentWillMount、componentWillReceiveProps、componentWillUpdate。
同时又提出两个新的钩子:getDerivedStateFromProps、getSnapshotBeforeUpdate。
*/
/*
1.初始化阶段:由ReactDOM。render()触发---初次渲染
1.consructor()
2.getDerivedStateFormProps
3.render()
4.componentDidMount() ===> 常用
一般在这个钩子中做一些初始化的事情,比如;开启定时器、发送网络请求、订阅消息
2.更新阶段:由组件内部this.setState()或父组件重新render触发
1.getDerivedStateFromProps
2.shouldComponentUpdate()
3.render()
4.getSnapshotBeforeUpdate
5.componentDidUpdate()
3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
1.componentWillUnmount() ===>常用
一般在这个钩子中做一些收尾的事情,比如关闭定时器、取消订阅消息
*/
class Demo extends React.Component {
constructor(props) {
console.log('最开始:constructor')
super(props)
this.state = {
count: 0 }
}
//组件将要挂载
// UNSAFE_componentWillMount() {
// console.log('组件将要挂载(17版本能用,但是会警告),componentWillMount')
// }
//在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用
//若state的值任何时候都取决于props,可以使用getDerivedStateFromProps
static getDerivedStateFromProps(props, state) {
console.log('getDerivedStateFromProps', props)
return null
}
//更新之前获取快照
getSnapshotBeforeUpdate() {
console.log('getSnapshotBeforeUpdate')
return '快照值'
}
//组件渲染的时候,状态更新之后
render() {
console.log('组件渲染的时候,状态更新之后:render')
const {
count } = this.state;
return (
<div>
<h2>求和为{
count}</h2>
<button onClick={
this.add}>加一</button>
<button onClick={
this.death}>卸载组件</button>
<button onClick={
this.force}>强制更新</button>
</div>
)
}
//组件挂载完成
componentDidMount() {
console.log('组件挂载完成:componentDidMount')
}
//控制组件更新的“阀门”(如果不写默认是true)
shouldComponentUpdate() {
console.log('控制组件更新的“阀门”:shouldComponentUpdate')
//返回值是true的才能继续往下一个生命周期走
return true
}
//组件将要更新(写了getDerivedStateFromProps UNSAFE_就不能存在)
// UNSAFE_componentWillUpdate() {
// console.log('组件将要更新(17版本能用,但是会警告):componentWillUpdate')
// }
//组件更新完成(快照值传到这里了)
componentDidUpdate(perProps,preState,snapValue) {
console.log('组件更新完成:componentDidUpdate',perProps,preState,snapValue)
}
//组件将要卸载
componentWillUnmount() {
console.log('组件将要卸载:componentWillUnmount')
}
//卸载组件
death = () => {
ReactDOM.unmountComponentAtNode(document.querySelector('#test'))
}
//强制更新 - 不更改setState的数据
force = () => {
this.forceUpdate()
}
add = () => {
let {
count } = this.state;
count++;
this.setState({
count })
}
}
ReactDOM.render(<Demo count={
199} />, document.querySelector('#test'))
</script>
</body>
</html>
1.初始化阶段:由ReactDOM。render()触发—初次渲染
1.consructor()
2.getDerivedStateFormProps
3.render()
4.componentDidMount() =>常用
一般在这个钩子中做一些初始化的事情,比如;开启定时器、发送网络请求、订阅消息
2.更新阶段:由组件内部this.setState()或父组件重新render触发
1.getDerivedStateFromProps
2.shouldComponentUpdate()
3.render()
4.getSnapshotBeforeUpdate
5.componentDidUpdate()
3.卸载组件:由ReactDOM.unmountComponentAtNode()触发
1.componentWillUnmount() =>常用
一般在这个钩子中做一些收尾的事情,比如关闭定时器、取消订阅消息
新增的两个钩子:
- getDerivedStateFromProps
//在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用
//若state的值任何时候都取决于props,可以使用getDerivedStateFromProps
static getDerivedStateFromProps(props, state) {
console.log('getDerivedStateFromProps', props)
return null
}
- getSnapshotBeforeUpdate
//更新之前获取快照
getSnapshotBeforeUpdate() {
console.log('getSnapshotBeforeUpdate')
return '快照值'
}
四、新旧的区别
回答方式:新的生命周期和旧的生命周期相比,它废弃了3个钩子:componentWillMount、componentWillReceiveProps、componentWillUpdate,同时又提出两个新的钩子:getDerivedStateFromProps、getSnapshotBeforeUpdate。
五、重要的钩子(常用)
1.render:初始化渲染或更新渲染调用
2.componentDidMount:开启监听,发送ajax请求
3.componentWillUnmount:做一些收尾的工作,如:清除定时器
六、即将废弃的钩子
1.componentWillMount
2.componentWillReceiveProps
3.componentWillUpdate
现在使用会出现警告,需要加上UNSAFE_前缀才能使用,以后可能会直接废弃。
以上就是React 中生命周期的内容,请大家关注《React 全家桶》专栏。
我会将自己平时项目中常见的问题以及笔试面试的知识在CSDN与大家分享,一起进步,加油。