理解React组件的生命周期

React提供了很多钩子函数使我们可以在合适的时间、合适的节点更新组件的状态,这些钩子是生命周期函数,想要使用React,我们必须掌握在钩子中可以做什么,不可以做什么。

??首先大家想一下在哪里发送请求比较合适 componentWillMountcomponentDidMountcomponentWillReceivePropscomponentDidUpdate?

组件3个阶段

组件的生命主要包括3个阶段: 挂载、更新、卸载,React 16开始还添加了错误处理。

挂载

组件被实例化并挂载在到dom树这一过程称为挂载

  • constructor()
  • componentWillMount()
  • render()
  • componentDidMount()

更新

当组件的属性或者状态改变时会重新渲染

  • componentWillReceiveProps()
  • shouldComponentUpdate()
  • componentWillUpdate()
  • render()
  • componentDidUpdate()

当执行this.forceUpdate时,shouldComponentUpdate将不会被触发

卸载

当一个组件被移出Dom树时,组件就会被卸载

  • componentWillUnmount()

Error Handling

  • componentDidCatch()

constructor

当组件被实例化时,构造函数就被会最先执行。需要注意的是constructor的第一行必须是super(props)语句。

DO

  1. 设置组件的初始状态
  2. bind function

简单解释下bind function,当类的方法作为事件处理函数时,有可能会丢失this指向,有两种常见的解决方案:

// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this); // 上面提到的bind function
使用箭头函数声明处理函数,个人比较推荐这种方案,代码简洁干净
handleClick = () => {}

DON’T

  1. 向后台发送请求进而更新组件状态
  2. 使用this.setState初始化

下图是强行在constructor中调用this.setState所发出的警告,在constructor中调用this.setState是没有任何作用的

componentWillMount

它也只会在挂载过程中被调用一次,它的作用和constructor没有太大差异。有很多人在componentWillMount中请求后台数据,认为这样可以更早的得到数据,componentWillMout是在render函数执行前执行的,虽然请求是在第一次render之前发送的,但是返回并不能保证在render之前完成。React中不推荐在componentWillMount中发送异步请求?。

还有一点需要了解: 在componentWillMount中执行this.setState是不会触发二次渲染的。仔细思考一下,componentWillMount好像没啥卵用了。正所谓存在即合理,在服务端渲染的场景中componentDidMount是不会被执行的,因此可以在componnetWillMount中发生AJAX请求。

DO

  1. 使用this.setState更新组件状态
  2. 发送AJAX请求(服务端渲染场景中)

DON’T

  1. 发送AJAX请求(浏览器渲染场景中)

componentDidMount

此函数只会被调用一次既组件挂载完成时,在render函数调用之后。组件挂载完成表示它的子组件也全部被挂载完成。父组件render ->子组件render->子子组件render ... ...子子组件DidMount -> 子组件DidMount -> 父组件DidMount。React就是个递归的世界。componentDidMount函数中可以发生异步请求。

DO

  1. 发送AJAX请求

DON’T

  1. this.setState更新状态,因为会触发二次渲染

componentWillReceiveProps

当父组件re-render时该钩子函数就会执行,即使所传入的属性没有改变。这个钩子最大的用途:组件的部分状态是依赖于属性时做状态同步使用,在其中使用this.setState是不会触发额外的渲染的,this.setState的状态更新和props触发的render合并一次进行。要合理使用componentWillReceiveProps需记住做好条件判断:

componentWillReceiveProps(nextProps) {
  if(nextProps.myProp !== this.props.myProps) {
    // nextProps.myProp has a different value than our current prop
  }
}

请不要尝试在componentWillReceiveProps中发送异步请求(React Fiber后该钩子函数可能会被触发多次)?

DO

  1. 根据Props的更新同步组件状态

DON’T

  1. 发生异步请求

shouldComponentUpdate

shouldComponentUpdate主要是用来优化React应用性能的,水平没达到一定高度就不要去动它了。组件的状态或者属性改变时都会触发该函数,但只有在返回true时,组件才会被重新渲染。

DO or DON’T
什么也不要做就对了?

componentWillUpdate

当我们没有覆写componentShouldUpdate时,componentWillUpdate会在其之后立即执行。当shouldComponent被覆写过时,componentWillUpdate主要用来取代componentWillReceiveProps,用来同步Props至组件的部分状态。

DO

  1. 同步Props到组件状态

DON’T

  1. 发生异步请求

componentDidUpdate

它和componentDidMount的功能类似,componentDidMount发生于组件的首次render之后,而componentDidUpdate则是发生于组件状态及属性变化所导致的re-render之后。主要是用来请求后台数据。和componentWillReceiveProps类似,做相应处理时,需要做属性是否变更的判断,如下面代码所示。有趣的一点: componentWillReceiveProps接收的参数是nextProps,componentDidUpdate接收的是preProps。

componentDidUpdate(prevProps) {
  if(prevProps.myProps !== this.props.myProp) {
    // this.props.myProp has a different value
    // ...
  }
}

DO

  1. 异步请求

DON’T

  1. this.setState更新状态,会触发二次渲染

componentWillUnmount

当组件被卸载时被调用,在这里主要做一些清理操作,清理定时器、关闭socket、清除监听器等等

componentDidCatch

React的错误机制:子组件中产生的错误若并未被捕获或处理会抛给父组件,若上层也一直没有处理,错误将会被抛至最顶层导致浏览器白屏。
React16开始添加了一个新的特性错误处理。componentDidCatch十分特别,它只可以处理子组件中产生的、未处理的错误,能够捕获的错误类型有子组件render函数中产生的错误及生命周期函数中产生的非异步错误。用法:

//父组件或祖宗组件中实现
componentDidCatch(errorString,errorInfo) {
  this.setState({
    error: errorString
  });
  ErrorLoggingTool.log(errorInfo);
}
render() {
  if(this.state.error) return <ShowErrorMessage error={this.state.error} />
  return (
    // render normal component output
  );
}

在哪请求数据

??首先大家想一下在哪里发送请求比较合适componentWillMountcomponentDidMountcomponentWillReceivePropscomponentDidUpdate?

componentDidMountcomponentDidUpdate中。?

本文是阅读了Understanding React — Component life-cycle和官方文档后做的总结,也可以说是我抄来得?,欢迎大家批评指正。code
React系列课程之 入门

Understanding React — Component life-cycle
React.Component
component-lifecycle-methods

【开发环境推荐】 Cloud Studio 是基于浏览器的集成式开发环境,支持绝大部分编程语言,包括 HTML5、PHP、Python、Java、Ruby、C/C++、.NET 小程序等等,无需下载安装程序,一键切换开发环境。 Cloud Studio提供了完整的 Linux 环境,并且支持自定义域名指向,动态计算资源调整,可以完成各种应用的开发编译与部署。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom