React和vue的生命周期函数

文章目录

React中的生命周期函数

React中旧版本的生命周期函数

React的生命周期函数 ----旧版本
初始化阶段 -----挂载阶段
constructor()
componentWillMount  (  )
render()
componentDidMount()
运行阶段 ----更新阶段
componentWillReaceiveProps()
shouldComponentUpdate()
ComponentWillUpdate()
render()
componentDidUpdate()
销毁阶段
componentWillUnmount()
错误异常处理阶段
componentDidcatch()

React中的新版本常用的8个生命周期函数

挂载阶段

1、constructor()
设定初始化的状态,以及定义事件,如果不初始化 state 或不进行方法绑定,则不需要为 React 组件实现构造函数。
在 React 组件挂载之前,会调用它的构造函数。在为 React.Component 子类实现构造函数时,应在其他语句之前前调用 super(props)。否则,this.props 在构造函数中可能会出现未定义的 bug。
在 constructor() 函数中不要调用 setState() 方法。如果你的组件需要使用内部 state,请直接在构造函数中为 this.state 赋值初始 state:

2、render() 方法是 class 组件中唯一必须实现的方法。
当 render 被调用时,它会检查 this.props 和 this.state 的变化并返回以下类型之一
React 元素。通常通过 JSX 创建。例如,< div /> 会被 React 渲染为 DOM 节点,
< MyComponent /> 会被 React 渲染为自定义组件,无论是 < div /> 还是 < MyComponent /> 均为 React 元素。
数组或 fragments。 使得 render 方法可以返回多个元素。欲了解更多详细信息,请参阅 fragments 文档。
Portals。可以渲染子节点到不同的 DOM 子树中。欲了解更多详细信息,请参阅有关 portals 的文档
字符串或数值类型。它们在 DOM 中会被渲染为文本节点
布尔类型或 null。什么都不渲染。(主要用于支持返回 test && < Child /> 的模式,其中 test 为布尔类型。)
render() 函数应该为纯函数,这意味着在不修改组件 state 的情况下,每次调用时都返回相同的结果,并且它不会直接与浏览器交互。

如需与浏览器进行交互,请在 componentDidMount() 或其他生命周期方法中执行你的操作。保持 render() 为纯函数,可以使组件更容易思考。

3、getDerivedStateFromProps () 一般不使用

getDerivedStateFromProps 会在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。它应返回一个对象来更新 state,如果返回 null 则不更新任何内容。
此方法适用于罕见的用例,即 state 的值在任何时候都取决于 props。例如,实现 < Transition> 组件可能很方便,该组件会比较当前组件与下一组件,以决定针对哪些组件进行转场动画。

派生状态会导致代码冗余,并使组件难以维护。
如果你需要执行副作用(例如,数据提取或动画)以响应 props 中的更改,请改用 componentDidUpdate。
如果只想在 prop 更改时重新计算某些数据,请使用 memoization helper 代替。
如果你想在 prop 更改时“重置”某些 state,请考虑使组件完全受控或使用 key 使组件完全不受控 代替。
此方法无权访问组件实例。如果你需要,可以通过提取组件 props 的纯函数及 class 之外的状态,在getDerivedStateFromProps()和其他 class 方法之间重用代码。

请注意,不管原因是什么,都会在每次渲染前触发此方法。这与 UNSAFE_componentWillReceiveProps 形成对比,后者仅在父组件重新渲染时触发,而不是在内部调用 setState 时。

4、componentDidMount()
componentDidMount() 会在组件挂载后(插入 DOM 树中)立即调用。依赖于 DOM 节点的初始化应该放在这里。如需通过网络请求获取数据,此处是实例化请求的好地方。

这个方法是比较适合添加订阅的地方。如果添加了订阅,请不要忘记在 componentWillUnmount() 里取消订阅

你可以在 componentDidMount() 里直接调用 setState()。它将触发额外渲染,但此渲染会发生在浏览器更新屏幕之前。如此保证了即使在 render() 两次调用的情况下,用户也不会看到中间状态。请谨慎使用该模式,因为它会导致性能问题。通常,你应该在 constructor() 中初始化 state。如果你的渲染依赖于 DOM 节点的大小或位置,比如实现 modals 和 tooltips 等情况下,你可以使用此方式处理

更新时阶段

1、componentDidUpdate(){
有条件的请求数据,实例化,dom操作
}
componentDidUpdate() 会在更新后会被立即调用。首次渲染不会执行此方法。
当组件更新后,可以在此处对 DOM 进行操作。如果你对更新前后的 props 进行了比较,也可以选择在此处进行网络请求。(例如,当 props 未发生变化时,则不会执行网络请求)。

componentDidUpdate(prevProps) {
  // 典型用法(不要忘记比较 props):
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}

你也可以在 componentDidUpdate() 中直接调用 setState(),但请注意它必须被包裹在一个条件语句里,正如上述的例子那样进行处理,否则会导致死循环。它还会导致额外的重新渲染,虽然用户不可见,但会影响组件性能。不要将 props “镜像”给 state,请考虑直接使用 props。
如果组件实现了 getSnapshotBeforeUpdate() 生命周期(不常用),则它的返回值将作为 componentDidUpdate() 的第三个参数 “snapshot” 参数传递。否则此参数将为 undefined。

注意
如果 shouldComponentUpdate() 返回值为 false,则不会调用 componentDidUpdate()。

2、shouldCompntDidUpdate() 默认返回值为true–提升
react性能的关键
根据 shouldComponentUpdate() 的返回值,判断 React 组件的输出是否受当前 state 或 props 更改的影响。默认行为是 state 每次发生变化组件都会重新渲染。大部分情况下,你应该遵循默认行为。

当 props 或 state 发生变化时,shouldComponentUpdate() 会在渲染执行之前被调用。返回值默认为 true。首次渲染或使用 forceUpdate(强制更新) 时不会调用该方法。

此方法仅作为性能优化的方式而存在。不要企图依靠此方法来“阻止”渲染,因为这可能会产生 bug。你应该考虑使用内置的 PureComponent 组件,而不是手动编写 shouldComponentUpdate()。PureComponent 会对 props 和 state 进行浅层比较,并减少了跳过必要更新的可能性。

如果你一定要手动编写此函数,可以将 this.props 与 nextProps 以及 this.state 与nextState 进行比较,并返回 false 以告知 React 可以跳过更新。请注意,返回 false 并不会阻止子组件在 state 更改时重新渲染。

我们不建议在 shouldComponentUpdate() 中进行深层比较或使用 JSON.stringify()。这样非常影响效率,且会损害性能。

目前,如果 shouldComponentUpdate() 返回 false,则不会调用 UNSAFE_componentWillUpdate(),render() 和 componentDidUpdate()。后续版本,React 可能会将 shouldComponentUpdate 视为提示而不是严格的指令,并且,当返回 false 时,仍可能导致组件重新渲染。

销毁阶段

componentWillUnmount()

componentWillUnmount() 会在组件卸载及销毁之前直接调用。在此方法中执行必要的清理操作,例如,清除 timer,取消网络请求或清除在 componentDidMount() 中创建的订阅等。

componentWillUnmount() 中不应调用 setState(),因为该组件将永远不会重新渲染。组件实例卸载后,将永远不会再挂载它。

错误异常阶段

1、static getDerivedStateFromerror()
此生命周期会在后代组件抛出错误后被调用。 它将抛出的错误作为参数,并返回一个值以更新 state

2、componentDidCatch()

此生命周期在后代组件抛出错误后被调用。 它接收两个参数:
error —— 抛出的错误。
info —— 带有 componentStack key 的对象,其中包含有关组件引发错误的栈信息。

vue中的生命周期

1、beforeCreate

在实例初始化之后,数据观测(data,observer)和 event/wathcher事件配置之前被调用。

2、created

在实例创建完成后被立即调用,在这一步。实例已完成以下的配置:数据观测(data,observer),property和方法的运算,watch/event事件回调,然而,挂载阶段还没开始

3、beforeMount

在挂载之前被调用:相关的render函数首次被调用。
该钩子在服务器端渲染期间不被调用

4、mounted

实例被挂载后调用,这时el被新创建的vm. e l 替 换 了 , 如 果 根 实 例 挂 载 到 了 一 个 文 档 内 的 元 素 上 , 当 m o u n t e d 被 调 用 时 , v m . el替换了,如果根实例挂载到了一个文档内的元素上,当mounted被调用时,vm. el替换了,如果根实例挂载到了一个文档内的元素上,当mounted被调用时,vm.el,也在文档内。注意mounted不会保证所有的子组件也都一起被挂载,如果你希望等到整个视图都渲染完毕,可以在mounted内部使用vm.$nextTick

5、beforeUpdate

数据更新时调用,这时el被新创建的vm. $ el替换了,如果根实例挂载到了一个文档内的元素上,当mounted被调用时vm.$el也在文档内。
注意mounted不会保证所有的子组件也都一起被挂载,如果你希望等到整个视图都渲染完毕,可以在mounted内部使用

该钩子在服务器端渲染期间不被调用

mounted: function () {
  this.$nextTick(function () {
    // Code that will run only after the
    // entire view has been rendered
  })
}

6、beforeUpdate

数据更新时调用,发生在虚拟DOM打补丁之前,这里适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器

该钩子在服务器端渲染期间不被调用,因为只有初次渲染在服务器端进行

7、Update

由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用该钩子
当这个钩子被调用时,组件DOM已经更新,所以你现在可以执行依赖于DOM的操作,然而在大多数情况下,你应该避免在此期间更改状态,如果要相应状态改变,通常最好使用计算属性或watcher取而代之
注意updated不会保证所有的子组件也都一起被重绘,如果你希望等到整个视图都重绘完毕,可以在updated里使用
该钩子在服务器端渲染期间不被调用

8、activated

被keep-alive缓存的组件激活时调用
该钩子在服务器端渲染期间不被调用

9、deactivated

被keep-alive缓存的组件停用时调用

10、beforeDestroy

实例销毁之前调用,在这一步,实例仍然完全可用。
该钩子在服务器渲染期间不被调用

11、destoryed

实例销毁后调用,该钩子被调用后,对应Vue实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁。

该钩子在服务器端渲染期间不被调用

12、errorCaptured

当捕获一个来自子孙组件的错误时被调用,此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串,此钩子可以返回false以阻止该错误继续向上传播

(err: Error, vm: Component, info: string) => ?boolean

错误传播规则:
1、默认情况下,如果全局的config.errorHandler被定义,所有的错误仍会发送它,因此这些错误仍然会向单一的分析服务的地方进行汇报

2、如果一个组件的继承或父级从属链路中存在多个errorCaptured钩子,则他们将会被相同的错误逐个唤起

3、如果此errorCaptured钩子自身抛出一个错误,则逐个新错误和原本被捕获的错误都会发送给全局的config.errorHandler

4、一个errorCaptured钩子能够返回false以阻止错误继续向上传播,本质上是说“逐个错误已经被搞定了,且应该被忽略”,他会阻止其他任何会被这个错误唤起的errorCaptured钩子和全局的config.errorHandler.

原文地址:https://blog.csdn.net/xiaokangna/article/details/120167298

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 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