react的生命周期和使用
完整的生命周期
我们都知道生命周期分为三个大阶段:
- 挂载
- 更新
- 卸载
挂载的时候我们我们有 constructor
、 getDerivedStateFromProps
、render
、 componentDidMount
(即将被废弃的生命周期不再写入,也不推荐大家继续使用)
挂载
constructor
它一般用于初始化state和绑定事件,只有在这里对state赋值直接赋值,而且最好不要在这里进行副作用的操作,后面会做解释。还有不要将props直接赋值给state
constructor(props) {
super(props);
this.state = {
name: this.props.name,
};
}
这种写法不会及时的更新状态
如下:
// 父组件
import React, {Component} from "react";
import Son from "./son";
class App extends Component {
constructor() {
this.state = {
number: 0,
};
}
render() {
const {number} = this.state;
return (
<div>
<button onClick={() => this.setState({number: number + 1})}>add</button>
<br/>
<Son name={this.state.number}/>
</div>
);
}
}
export default App;
// 子组件
import React, {Component} from "react";
class Son extends Component {
constructor(props) {
super(props);
this.state = {
name: this.props.name,
};
}
render() {
return (
<div>
<p>将props赋值给了子组件state</p>
{this.state.name}
<br/>
<p>直接使用了this.props.number</p>
{this.props.name}
</div>
);
}
}
export default Son;
父组件点击一次以后,子组件中直接使用 this.props.number
的更新了,而通过赋值给state的没有更新。
-------------------------------------------------------------------------------------------------------------------**
getDerivedStateFromProps
-------------------------------------------------------------------------------------------------------------------
render
此方法在挂载阶段肯定会被调用,而在更新阶段会取决于 UNSAFE_componentWillUpdate和shouldComponentUpdate()返回值影响
它应该返回以下类型之一
- React 元素。通常通过 JSX 创建。例如,
<div />
会被 React 渲染为 DOM 节点,<MyComponent />
会被 React 渲染为自定义组件,无论是<div />
还是<MyComponent />
均为 React 元素。- 数组或 fragments。 使得 render 方法可以返回多个元素。欲了解更多详细信息,请参阅 fragments 文档。
- Portals。可以渲染子节点到不同的 DOM 子树中。欲了解更多详细信息,请参阅有关 portals 的文档
- 字符串或数值类型。它们在 DOM 中会被渲染为文本节点
- 布尔类型或
null
。什么都不渲染。(主要用于支持返回test && <Child />
的模式,其中 test 为布尔类型。)
componentDidMount
会在组件挂载到dom上的时候立即调用,如果这个时候调用setState的话会再次触发render,但是会在屏幕更新出来之前完成渲染。下面示例:
import React, {Component} from "react";
class SonTwo extends Component {
constructor(props) {
super(props);
this.state = {
number: 0,
};
}
componentDidMount() {
this.setState({
number: this.state.number + 1,
});
}
render() {
console.log("我执行了", this.state.number);
return (
<div>
{this.state.number}
</div>
);
}
}
export default SonTwo;
![image.png](https://cdn.nlark.com/yuque/0/2020/png/425103/1586445215750-938b1066-9f85-4793-848f-81b1534faa69.png#align=left&display=inline&height=138&name=image.png&originHeight=138&originWidth=237&size=4367&status=done&style=shadow&width=237)
**这里为什么会出现4次,是因为 react的 **[**严格模式**](https://zh-hans.reactjs.org/docs/strict-mode.html#gatsby-focus-wrapper)
严格模式不能自动检测到你的副作用,但它可以帮助你发现它们,使它们更具确定性。通过故意重复调用以下函数来实现的该操作:
- class 组件的
constructor
,render
以及shouldComponentUpdate
方法- class 组件的生命周期方法
getDerivedStateFromProps
- 函数组件体
- 状态更新函数 (即
setState
的第一个参数)- 函数组件通过使用
useState
,useMemo
或者useReducer
所以使用的时候需要注意如果出现循环更改可能会出现性能问题
更新
getDerivedStateFromProps
shouldComponentUpdate
每次props或者state变化是render之前它会被调用,默认是正常调用render,但是如果这个周期函数返回false就会停止组件的渲染,不过父组件的state或者props变化不引起本组件改变,其子组件的state改变依然会更新
// 父组件
import React, {Component} from "react";
import Son from "./son";
class App extends Component {
constructor(props) {
super(props);
this.state = {
number: 0,
};
}
shouldComponentUpdate(nextProps, nextState, nextContext) {
return nextState.number > 10;
}
render() {
const {number} = this.state;
return (
<div style={{border: "1px solid red", margin: "6px"}}>
<button onClick={() => this.setState({number: number + 1})}>add
</button>
<br/>
<span>父组件中的number: </span>{this.state.number}
<br/>
<Son number={this.state.number}/>
{/*<SonTwo/>*/}
</div>
);
}
}
export default App;
// 子组件
import React, {Component} from "react";
class Son extends Component {
constructor(props) {
super(props);
this.state = {
number: 0,
};
}
render() {
return (
<div style={{border: "1px solid blue", margin: "6px", padding: "20px"}}>
<button onClick={() => {
this.setState({
number: this.state.number + 1,
});
}}>ADD
</button>
<br/>
<br/>
<span>父组件中的值: </span>{this.props.number}
<br/>
<span>子组件中的值: </span>{this.state.number}
</div>
);
}
}
export default Son;
效果如图:
图1 是点击了外层的父节点的add后子节点并没接收到父节点传递过来的值,因为父节点的render并没有被触发。
图2 是点击了内层的子节点上ADD后发现子组件触发了render
-------------------------------------------------------------------------------------------------------------------**
render
同上
-------------------------------------------------------------------------------------------------------------------
getSnapshotBeforeUpdate
componentDidUpdate
在更新结束和被调用,首次渲染不会触发它,首次渲染触发的 componentDidMount
可以做的 DOM
操作或者发起请求,它也可以,只是更新渲染结束后不会再触发componentDidMount
, 而触发的是它。可以基于更新前后的state或者props的变化来做出相应的请求或者操作
重点对于状态的更改需要做出判断
你也可以在
componentDidUpdate()
中直接调用setState()
,但请注意它必须被包裹在一个条件语句里,正如上述的例子那样进行处理,否则会导致死循环。
-------------------------------------------------------------------------------------------------------------------**
卸载
componentWillUnmount
componentWillUnmount()
会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在componentDidMount()
中创建的订阅等。
componentWillUnmount()
中不应调用setState()
,因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。
react的生命周期和使用的更多相关文章
- react.js 生命周期componentDidUpdate的另类用法:防止页面过渡刷新
场景:数据新增成功之后,需要返回原来的查询表,这时候的查询,需要使用react的生命周期:componentDidUpdate componentDidUpdate() 这个生命周期的作用是当prop ...
- React的生命周期
我们先来看一张图,其实看完这张图基本就懂了,如果还不懂,请继续往下看. getDefaultProps 执行过一次后,被创建的类会有缓存,映射的值会存在this.props,前提是这个prop不是父组 ...
- 附实例!图解React的生命周期及执行顺序
本文由云+社区发表 作者:前端林子 1.七个可选的生命周期 可以结合下图来看: (1) componentWillMount() 仅在render()方法前被调用一次,如果在该方法中调用了setSta ...
- React之生命周期
哈喽,这是我的第一篇博客,请大家多多关照~ 追根溯源:What's the lifeCycle? 生命周期函数指在某一时刻组件会自动调用执行的函数: React生命周期概览: 接下来我们就着生命周期的 ...
- React组件生命周期小结
React组件生命周期小结 下面所写的,只适合前端的React.(React也支持后端渲染,而且和前端有点小区别,不过我没用过.) 相关函数 简单地说,React Component通过其定义的几个函 ...
- React—组件生命周期详解
React—组件生命周期详解 转自 明明的博客 http://blog.csdn.net/slandove/article/details/50748473 (非原创) 版权声明:转载请注明出处,欢 ...
- React 函数生命周期
React 函数生命周期基础 1 ,概念 在组件创建.到加载到页面上运行.以及组件被销毁的过程中,总是伴随着各种各样的事件,这些在组件特定时期,触发的事件,统称为组件的生命周期:* 2,组件生命周 ...
- 帮你理清React的生命周期
这是一个从印记中文 | react官方文档提取总结的,算是帮自己理清并且强化记忆React的生命周期,以便以后编写组件的时候能够有更清晰的思路.本文如有纰漏,欢迎指正 整体上来讲,React生命周期分 ...
- 七天接手react项目 —— 生命周期&受控和非受控组件&Dom 元素&Diffing 算法
生命周期&受控和非受控组件&Dom 元素&Diffing 算法 生命周期 首先回忆一下 vue 中的生命周期: vue 对外提供了生命周期的钩子函数,允许我们在 vue 的各个 ...
- 野心勃勃的React组件生命周期
当你还在写着Angular指令,过滤器,注入,服务,提供者,视图模版的时候,是不是觉得很烦,好在这个时候,React已经神一样的出现在历史舞台. React组件 React实现了UI=Fn(St ...
随机推荐
- QT个人笔记
1.QT的setCursor(Qt::CrossCursor) 干什么用 ui->View->setCursor(Qt::CrossCursor); setCursor函数用于设置窗口上的 ...
- C++语言程序设计实验一 类与对象
Complex.hpp文件源码: #include <iostream> using namespace std; class Complex { public: Complex(floa ...
- 数据类型之字符串(string)(一)
1.引号括起的都是字符串(可以时空格),可以是''(单引号).""(双引号).''''''(三引号).""""""(我还 ...
- flannel 关闭SNAT
flannel 关闭SNAT 默认情况下,flannel 访问集群外网络是通过 SNAT 成宿主机 ip 方式,在一些金融客户环境中为了能实现防火墙规则,需要直接针对 POD ip 进行进行规则配置, ...
- vue 基础 v-text v-html v-model v-cloak v-bind
v-text 纯文本绑定 v-html 会解析html标签 <p v-html="rawHtml"></p> var a=new Vue({ el:&q ...
- 1414:【17NOIP普及组】成绩
1414:[17NOIP普及组]成绩 时间限制: 1000 ms 内存限制: 65536 KB提交数: 27975 通过数: 17779 [题目描述] 牛牛最近学习了 C++入 ...
- 2022-05-26内部群每日三题-清辉PMP
1.在执行关键路径上的一项活动时,职能主管将涉及这个活动的两个项目资源调去支持解决某个应急情况,项目经理应该怎么做? A.实施应急计划 B.快速跟进关键路径 C.与职能经理协商分配替代资源 D.将该问 ...
- vue路由跳转当前路由刷新
在app.vue里面定义 reload() { this.isRouterAlive = false this.$nextTick(function () { ...
- reduced form(简化式)和structural form(结构式)
在复习软件构造的时候,我发现了这样一道练习题 例题要求我们对照给出的RI和AF画出相应的映射图.在这里产生了一个疑问,什么是reduced form?是分子小于分母的意思吗? 但是根据给出的答案,并不 ...
- win10上打包的qt程序放到win7上打不开的解决方法
在win 10 上编写并打包发布了qt5.12.3 msvc2017 32bit的qt程序,在其他win10 电脑上都能正常运行,但是放到win7电脑上,运行exe时依次出现缺少"msvcp ...