202-React.Component组件、生命周期
一、概述
React可以将组件定义为类或函数。定义为类的组件当前提供了更多的功能。要定义React组件类,您需要扩展React.Component:
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
必须在React.Component子类中定义的唯一方法称为render()。描述的所有其他方法都是可选的。
强烈建议不要创建您自己的基础组件类。在React组件中,代码重用主要是通过组合而不是继承来实现的。
二、组件的生命周期
每个组件都有几个“生命周期方法”,您可以重写以在该进程中的特定时间运行代码。您可以使用此生命周期图作为备忘单。在下面的列表中,常用的生命周期方法标记为粗体。其余的存在于相对罕见的用例中。
2.1、创建【Mount】
2.2、更新
static getDerivedStateFromProps()
shouldComponentUpdate()
render()
getSnapshotBeforeUpdate()
componentDidUpdate()
2.3、卸载【Unmounting】
三、其他API
Each component also provides some other APIs:
Class Properties
Instance Properties
四、详细介绍
4.1、render【渲染】
render()方法是类组件中唯一需要的方法。调用时,它应该检查this.props和this.state并返回以下类型之一:React elements.Arrays and fragments. Portals. String and numbers. Booleans or null
.
注意:如果shouldComponentUpdate()返回false,则不会调用render()。
4.2、constructor【构造方法】
如果您没有初始化状态并且没有绑定方法,则不需要为您的React组件实现构造函数。
通常,React构造函数只用于两个目的:通过将对象分配给this.state来初始化本地状态。 将事件处理程序方法绑定到实例。
constructor(props) {
super(props);
// Don't call this.setState() here!
this.state = { counter: 0 };
this.handleClick = this.handleClick.bind(this);
}
构造函数是你应该直接分配this.state的唯一地方。在所有其他方法中,您需要使用this.setState()。
避免在构造函数中引入任何副作用或订阅。对于这些用例,请改用componentDidMount()
以下是错误的
constructor(props) {
super(props);
// Don't do this!
this.state = { color: props.color };
}
4.3、componentDidMount
componentDidMount()在装载组件(插入树中)后立即调用。需要DOM节点的初始化应该放在这里。如果您需要从远程端点加载数据,则这是一个实例化网络请求的好地方。
此方法是设置任何订阅的好地方。如果你这样做,不要忘记在componentWillUnmount()中取消订阅。
您可以立即在componentDidMount()中调用setState()。它会触发一个额外的渲染,但它会在浏览器更新屏幕之前发生。这保证即使render()在这种情况下被调用两次,用户也不会看到中间状态。请谨慎使用此模式,因为它经常会导致性能问题。在大多数情况下,您应该能够在构造函数()中分配初始状态。然而,当你需要在渲染依赖于它的大小或位置的东西之前测量DOM节点时,它可能需要类似于模态和工具提示的情况。
4.4、componentDidUpdate(prevProps, prevState, snapshot)
在更新发生后立即调用componentDidUpdate()。此方法不用于初始渲染。
在更新组件时,将此用作在DOM上操作的机会。只要您将当前的道具与以前的道具进行比较(例如,如果道具没有改变,则可能不需要网络请求),这也是做网络请求的好地方。
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}
您可以在componentDidUpdate()中立即调用setState(),但请注意它必须像上例那样包装,否则会导致无限循环。它也会导致额外的重新渲染,虽然用户不可见,但会影响组件的性能。
如果您的组件实现getSnapshotBeforeUpdate()生命周期(很少见),则它返回的值将作为第三个“快照”参数传递给componentDidUpdate()。否则这个参数将是未定义的。
注意:如果shouldComponentUpdate()返回false,则不会调用componentDidUpdate()。
4.5、componentWillUnmount
componentWillUnmount()在组件被卸载并销毁之前立即被调用。在此方法中执行任何必要的清理,例如使定时器无效,取消网络请求或清理在componentDidMount()中创建的任何预订。
您不应该在componentWillUnmount()中调用setState(),因为组件不会被重新渲染。一旦组件实例被卸载,它将永远不会再被挂载。
4.6、很少使用的生命周期方法
https://reactjs.org/docs/react-component.html#rarely-used-lifecycle-methods
4.7、整个生命周期简介
getDefaultProps
object getDefaultProps()
执行过一次后,被创建的类会有缓存,映射的值会存在this.props
,前提是这个prop不是父组件指定的
这个方法在对象被创建之前执行,因此不能在方法内调用this.props
,另外,注意任何getDefaultProps()
返回的对象在实例中共享,不是复制
getInitialState
object getInitialState()
控件加载之前执行,返回值会被用于state的初始化值
componentWillMount
void componentWillMount()
执行一次,在初始化render
之前执行,如果在这个方法内调用setState
,render()
知道state发生变化,并且只执行一次
render
ReactElement render()
render的时候会调用render()
会被调用
调用render()
方法时,首先检查this.props
和this.state
返回一个子元素,子元素可以是DOM组件或者其他自定义复合控件的虚拟实现
如果不想渲染可以返回null或者false,这种场景下,React渲染一个<noscript>
标签,当返回null或者false时,ReactDOM.findDOMNode(this)
返回null render()
方法是很纯净的,这就意味着不要在这个方法里初始化组件的state,每次执行时返回相同的值,不会读写DOM或者与服务器交互,如果必须如服务器交互,在componentDidMount()
方法中实现或者其他生命周期的方法中实现,保持render()
方法纯净使得服务器更准确,组件更简单
componentDidMount
void componentDidMount()
在初始化render之后只执行一次,在这个方法内,可以访问任何组件,componentDidMount()
方法中的子组件在父组件之前执行
从这个函数开始,就可以和 JS 其他框架交互了,例如设置计时 setTimeout 或者 setInterval,或者发起网络请求
shouldComponentUpdate
boolean shouldComponentUpdate(
object nextProps, object nextState
)
这个方法在初始化render
时不会执行,当props或者state发生变化时执行,并且是在render
之前,当新的props
或者state
不需要更新组件时,返回false
shouldComponentUpdate: function(nextProps, nextState) {
return nextProps.id !== this.props.id;
}
当shouldComponentUpdate
方法返回false时,讲不会执行render()
方法,componentWillUpdate
和componentDidUpdate
方法也不会被调用
默认情况下,shouldComponentUpdate
方法返回true防止state
快速变化时的问题,但是如果·state
不变,props
只读,可以直接覆盖shouldComponentUpdate
用于比较props
和state
的变化,决定UI是否更新,当组件比较多时,使用这个方法能有效提高应用性能
componentWillUpdate
void componentWillUpdate(
object nextProps, object nextState
)
当props
和state
发生变化时执行,并且在render
方法之前执行,当然初始化render时不执行该方法,需要特别注意的是,在这个函数里面,你就不能使用this.setState
来修改状态。这个函数调用之后,就会把nextProps
和nextState
分别设置到this.props
和this.state
中。紧接着这个函数,就会调用render()
来更新界面了
componentDidUpdate
void componentDidUpdate(
object prevProps, object prevState
)
组件更新结束之后执行,在初始化render
时不执行
componentWillReceiveProps
void componentWillReceiveProps(
object nextProps
)
当props
发生变化时执行,初始化render
时不执行,在这个回调函数里面,你可以根据属性的变化,通过调用this.setState()
来更新你的组件状态,旧的属性还是可以通过this.props
来获取,这里调用更新状态是安全的,并不会触发额外的render
调用
componentWillReceiveProps: function(nextProps) {
this.setState({
likesIncreasing: nextProps.likeCount > this.props.likeCount
});
}
componentWillUnmount
void componentWillUnmount()
当组件要被从界面上移除的时候,就会调用componentWillUnmount()
,在这个函数中,可以做一些组件相关的清理工作,例如取消计时器、网络请求等
总结
React Native的生命周期,其中最上面的虚线框和右下角的虚线框的方法一定会执行,左下角的方法根据props
state
是否变化去执行,其中建议只有在componentWillMount
,componentDidMount
,componentWillReceiveProps
方法中可以修改state
值
五、其他API
与上面的生命周期方法(React为您调用)不同,下面的方法是您可以从组件调用的方法。
其中只有两个:setState()和forceUpdate()。
5.1、setState(updater[, callback])
setState()将对组件状态的更改排队,并告诉React该组件及其子组需要使用更新的状态重新呈现。这是您用来更新用户界面以响应事件处理程序和服务器响应的主要方法。
setState()并不总是立即更新组件。它可能会批处理或推迟更新,直到稍后。
第一个参数是带签名的更新函数:
(prevState, props) => stateChange
prevState是对之前状态的引用。它不应该直接变异。相反,应该通过建立一个基于prevState和道具输入的新对象来表示更改。例如,假设我们想通过props.step来增加状态值:
this.setState((prevState, props) => {
return {counter: prevState.counter + props.step};
});
setState()的第二个参数是一个可选的回调函数,一旦setState完成并且组件被重新渲染,该函数将被执行。通常我们建议使用componentDidUpdate()代替这种逻辑。
更多详细:
https://reactjs.org/docs/react-component.html#setstate
5.2、component.forceUpdate(callback)
默认情况下,当你的组件的状态或道具改变时,你的组件将重新渲染。如果你的render()方法依赖于其他的数据,你可以通过调用forceUpdate()来告诉React组件需要重新渲染。
调用forceUpdate()将导致在组件上调用render(),跳过shouldComponentUpdate()。这将触发子组件的正常生命周期方法,包括每个子组件的shouldComponentUpdate()方法。如果标记更改,React仍然只会更新DOM。
通常你应该尽量避免使用forceUpdate(),只能从render.props和this.state中读取render()。
六、类属性
6.1、默认属性
class CustomButton extends React.Component {
// ...
} CustomButton.defaultProps = {
color: 'blue'
};
6.2、displayName
字符串用于调试消息。通常,您不需要明确设置它,因为它是根据定义组件的函数或类的名称推断出来的。如果要为调试目的显示不同的名称或创建高阶组件时,可能需要显式设置它,
七、实例属性
7.1、props
不能被修改
7.2、state
状态包含特定于此组件的数据,这些数据可能随时间而改变。状态是用户定义的,它应该是一个普通的JavaScript对象。
202-React.Component组件、生命周期的更多相关文章
- React 之 组件生命周期
React 之 组件生命周期 理解1) 组件对象从创建到死亡它会经历特定的生命周期阶段2) React组件对象包含一系列的勾子函数(生命周期回调函数), 在生命周期特定时刻回调3) 我们在定义组件时, ...
- [React] 多组件生命周期转换关系
前段时间一直在基于React做开发,最近得空做一些总结,防止以后踩坑. 言归正传,React生命周期是React组件运行的基础,本文主要是归纳多组件平行.嵌套时,生命周期转换关系. 生命周期 Reac ...
- React Class组件生命周期
一.react组件的两种定义方式 1.函数组件,简单的函数组件像下面这样,接收Props,渲染DOM,而不关注其他逻辑 function Welcome(props) { return <h1& ...
- react之组件生命周期
四个阶段 初始化 运行中 销毁 错误处理(16.3以后) 初始化 constructor static getDerivedStateFromProps() componentWillMount() ...
- [深入React] 7.组件生命周期
生命周期一共分三段:初始化,运行中,销毁.按照顺序: 初始化 getDefaultProps():Object 全局只会调用一次,为当前类生成的默认props,会被父组件传入的同名props覆盖. g ...
- 【学】React的学习之旅2 - React Component的生命周期
分成三个状态: Mounted Update Unmounted Mounted:当我们看到组件在浏览器中从无到有的效果的时候,mounted已经结束了,这个组件已经被mounted了 有这个阶段有2 ...
- 【JAVASCRIPT】React学习-组件生命周期
摘要 整理组件加载过程,详细见官方文档:https://facebook.github.io/react/docs/react-component.html mount 过程 1)constructo ...
- 【React】组件生命周期
初始化阶段 getDefaultPropos:只调用一次,实力之间共享引用 getInitialState:初始化每个实例特有的状态 componentWillMount:render之前最后一次修改 ...
- React组件生命周期小结
React组件生命周期小结 下面所写的,只适合前端的React.(React也支持后端渲染,而且和前端有点小区别,不过我没用过.) 相关函数 简单地说,React Component通过其定义的几个函 ...
- React Native 中的component 的生命周期
React Native中的component跟Android中的activity,fragment等一样,存在生命周期,下面先给出component的生命周期图 getDefaultProps ob ...
随机推荐
- TFS对签入文件忽略设置,解决pdb弹出警告
我们在使用TFS项目老是出现冲突,要么编译的时候 提示PDB被签出这类的大量弹出,很烦人. 在群友的指点下,对签入文件进行限制.对PDB禁止签入以后,整个世界安静了.非常感谢 TFS=>服务器管 ...
- round()
round() 用于对一个数值进行四舍五入,如果接收两个参数,则第二个参数表示保留多少位小数 In [1]: round(1.5324) Out[1]: 2.0 In [2]: round(1.532 ...
- 写了一个简单的CGI Server
之前看过一些开源程序的源码,也略微知道些Apache的CGI处理程序架构,于是用了一周时间,用C写了一个简单的CGI Server,代码算上头文件,一共1200行左右,难度中等偏上,小伙伴可以仔细看看 ...
- Nginx遇上Access Denied提示怎么解决
这几天在摆弄linux下面的各种服务器,对nginx非常有兴趣. 于是把phpmyadmin传上去了,先是phpmyadmin配了半天,结果配好之后发现phpmyadmin一些logo.css.js文 ...
- 什么叫做hack
由于不同的浏览器,比如Internet Explorer 6,Internet Explorer 7,Mozilla Firefox等,对CSS的解析认识不一样,因此会导致生成的页面效果不一样,得不到 ...
- 新版本读取老版本文件崩溃BUG
读取文件匹配代码 BOOL CWBPage::LoadFromFile(CFile *pFile, LONGLONG& lOff, ULONGLONG lFileLength) { if (p ...
- Django学习笔记 开发环境搭建
为什么使用django?1.支持快速开发:用python开发:数据库ORM系统,并不需要我们手动地构造SQL语句,而是用python的对象访问数据库,能够提升开发效率.2.大量内置应用:后台管理系统a ...
- thinkphp5 Windows下用Composer引入官方GitHub扩展包
很多新手,比如说我,写代码就是在windows下,所以总会遇到很多不方便的地方,比如说GitHub上面的代码更新了,要是你在linux,只要几行命令就可以搞定更新了,在windows下面,你需要用到C ...
- Python实现自动登录/登出校园网网关
学校校园网的网络连接有免费连接和收费连接两种类型,可想而知收费连接浏览体验更佳,比如可以访问更多的网站.之前收费地址只能开通包月服务才可使用,后来居然有了每个月60小时的免费使用收费地址的优惠.但是, ...
- CSS-自定义高度的元素背景图如何自适应以及after伪元素在ie下的处理
我都好久没更新了! 遇到一个效果,之前没有考虑清楚,设置了固定高度,到了后边,产品要加长,我就觉得设计得从新弄张长点的背景图!这不多余么? 其实分析原图还是可以再切分,再细化到不用改设计图,让我们前端 ...