微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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.

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

相关推荐