玩转 React(五)- 组件的内部状态和生命周期
文章标题总算是可以正常一点了…… 通过之前的文章我们已经知道:在 React 体系中所谓的 "在 JavaScript 中编写 HTML 代码" 指的是 React 扩展了 JavaScript 的语法,也就是 JSX。JSX 语法中可以以类似 HTML 语法的方式使用 React 组件,从而编写 React 组件就有一种创造一个新的 HTML 标签的体验。 上一篇文章《玩转 React(四)- 创造一个新的 HTML 标签》介绍了如何来创建一个 React 组件,以及组件的属性。了解到组件的视图是属性的映射,通过改变组件属性可以触发组件重新渲染,从而改变组件的视图。其实组件的视图并不仅仅是由属性映射来的,本篇将介绍另一种可以触发组件重新渲染的方式,即组件的内部状态(state),严格来说组件的视图是由属性和内部状态映射而来的,即: 另外本文中会介绍一个通过类继承方式定义的组件的生命周期,以及在各个生命周期函数中能做什么,不能或尽量不要做什么。 内容摘要
以上是本文的内容摘要,如果你已经知道我要说的是什么,那么就没有必要继续看下去了,节约时间。 组件的内部状态此前,我们已经了解到可以通过 下面是官方文档中一个展示时钟的例子,我简单改造了下: https://codepen.io/Sarike/pen... 例子中定义了一个 然而在很多实际场景中,对于一个时钟组件,我们希望它有更好的封装性和复用性,也就是说我们希望只调用一次 要达到这个目的,就需要组件的内部状态来支持。组件有一个特殊的属性 https://codepen.io/Sarike/pen... 这样 上面例子中有用到 改造后的例子,我们只需要调用一次 初始化组件内部状态在创建一个拥有内部状态的组件时,我们需要对内部状态进行初始化,即设置组件最初的状态是什么。做法很简单,就是在构造函数 class MyComponent extends React.Component { constructor(props) { super(props); // 这行代码不能少哦 this.state = { name: "Lucy" } } } setState 大多数情况下是异步的
https://codepen.io/Sarike/pen... 如果希望上面示例代码正常工作,你需要通过回调函数的方式来生成下一个 state,如下所示: this.setState(preState => ({value: preState.value + 1})); this.setState(preState => ({value: preState.value + 2})); this.setState(preState => ({value: preState.value + 3})); 所以,直接基于当前 那为什么说多数情况下是异步的呢?难道有些情况下不是异步的吗?是的,实际上只有在 React 能控制的事件处理过程中调用的 在某些特殊的组件中,可能需要通过 参考:https://www.zhihu.com/questio... 不要直接通过 this.state 来更新组件状态这一点跟属性类似,直接通过 生命周期函数一个组件被我们创造到这个世界上之后,在使用它时,它的每个实例都是有一定生命周期的,下面这张图说明了一个组件实例的生命周期:
图片来源:https://tylermcginnis.com/an-...,这张图略微有点老,不过结合下文来看也没什么问题。 下面我们来解释一下上面这张图。 组件初始化:constructor我们定义的每一个组件,都是一个类(class),这些类被实例化后才能作为 React DOM 中的一个节点渲染到页面上。所以,当我们通过 实例化主要做的事情:
componentWillMount在组件被渲染到页面上之前执行,在组件的整个生命周期内只执行一次。在这里可以调用 该函数执行完后会立马执行 componentDidMount组件被渲染到页面上后立马执行,在组件的整个生命周期内只执行一次。这个时候是做如下操作的好时机:
在这里可以调用 componentWillReceivePropscomponentWillReceiveProps(nextProps) 该声明周期函数可能在两种情况下被调用:
你只要知道,当该函数被调用时,并不一定是因为属性发生了变化。 在这里也可以调用 shouldComponentUpdateshouldComponentUpdate(nextProps,nextState) 这是一个询问式的生命周期函数,所以该函数需要一个返回值 此处不能调用 由于组件属性或者内部状态被改变时都触发组件重新渲染,所以该函数接受两个参数:新的属性(nextProps)、新的状态(nextState)。 在处理该声明周期函数时,切记要兼顾属性和状态,不能只顾其一,不然很容易踩坑。例如:某位同学只依据属性来判断是否触发重新渲染,而忽略了内部状态,这样就导致你无论如何 在上篇文章中我们提到类继承方式定义组件时说到,React 提供了两个基类,一个是 但是比对过程出于性能考虑,只是进行浅比对,也就是只比对对象的第一级字段,而且是否发生变化是通过 Object.is 方法类判断的。所以会导致有时候发生变化了组件没有更新,没有变化却触发了重新渲染过程。这个在这里不再赘述,想深入探讨可以扫描问候的二维码加我微信好友(我的微信:leobaba88)。 componentWillUpdate当组件 该函数中不能调用 该函数在函数第一次渲染的时候不会执行。 componentDidUpdatecomponentDidUpdate(prevProps,prevState) 在组件重新渲染过程中,重新执行 在此处是做这些事情的好时机:
componentWillUnmount当组件被从页面中移除之前调用,此时是清理战场的好时机,如清理定时器、中指网络请求等。 componentDidCatchcomponentDidCatch(error,info) 这是 React 16 新加入的一个生命周期函数。定义该生命周期函数的组件将会成为一个错误边界,错误边界这个词非常形象,它可以有效地将错误限制在一个有限的范围内,而不会导致整个应用崩溃,防止一颗耗子屎坏了一锅汤。 错误边界组件,可以捕获其整个子组件树内发生的任何异常,但是却不能捕获自身的异常。 下面是官方的一个示例,大家感受下: https://codepen.io/gaearon/pe... 最后(微信群)这篇文章来的有点慢,非常抱歉。 另外为了方便大家阅读,我将所有文章的链接更新到第一篇文章 《玩转React(一)- 前言》 中。 文字的表现范围毕竟有限,为了方便大家交流,我建了一个微信群,对 React 感兴趣的同学可以进群一起交流、学习,由于微信群邀请的时间限制,大家可以先扫描下面二维码,加我好友,我拉大家进群:
我的微信: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |