likes
comments
collection
share

彻底理清vue和react的生命周期钩子和hooks

作者站长头像
站长
· 阅读数 72
阅读本文章大约需要10分钟,将和各位一起彻底理清vue2,vue3,react他们的生命周期和hooks之间的区别。

首先是生命周期的概念,不管vue还是react他们的每一个组件都存在几个阶段:即挂载,更新,卸载等,这些阶段的命名和定义在vue和react中略有不同,但原理是一样的。生命周期钩子就在这些阶段时被调用的函数。

Hooks(在vue3中是Vue Composition API)。它是一系列函数,允许我们在组件里管理状态,使用其他vue和react的特性。React Hooks 和 Vue Composition API 在概念上很相似,都提供了一种函数式的方式来管理组件状态和副作用。通过Hooks,开发者可以更专注于组件的核心逻辑,使得代码更加清晰和可维护。

Vue2Vue3: Vue的生命周期钩子更加精细,可以在更多的阶段进行操作。它的使用更为显式,每个钩子都有明确的命名和调用时机。

Vue2

生命周期:beforeCreate,created,beforeMount,mounted,beforeUpdate, Updated,activated,deactivated,beforeDestroy,destroyed等。

你可以在每个生命周期中根据逻辑做不同的操作,这里不再累述。

Hooks:Vue2没有官方的Hooks,但是你可以使用Mixin,scoped,slots, Provide / Inject等实现类似于 Hooks 的效果,管理组件的状态和副作用。 举例:

// mixinA.js

export default {
  datafunction() {
    return {valueA:’’}
  },
  methods: {
    doSomeThing(){
        this.valueA=’hollo world’;
        return this.valueA;
    }
    },
};

组件中使用:

<script>
import MixinA from "./mixins/mixinA.js";

export default {
    mixins: [MixinA],
    data() {
        return{
            Name:’Tom
        }
    },
    methods: {
        clickHandle(){
            console.log(this.doSomeThing()+’ ’+this.Name);
        }
    }
};

</script>

Vue3:

生命周期:beforeCreate created beforeMount mounted beforeUpdate updated beforeUnmount unmounted等,用于处理组件的生命周期,在组件的每个不同阶段被调用。

Hooks

Vue3引入的新特性Vue Composition API,包括:ref reactive computed watch provide 和 inject onBeforeMount, onMounted, onBeforeUpdate, onUpdated,onBeforeUnmount,onUnmounted等。

举例:创建自定义Hook,我们通过onMounted生命周期钩子,在组件挂载后自动发起请求。

*// useFetch.js*
import { ref, onMounted } from 'vue';
import axios from 'axios';

export function **useFetch**(url) {
  const data = ref(null);
  const error = ref(null);
  const loading = ref(true);

  async function **fetchData**() {
    try {
      const response = await axios.get(url);
      data.value = response.data;
    } catch (err) {
      error.value = err;
    } finally {
      loading.value = false;
    }
  }
  onMounted(fetchData);
  return { data, error, loading };

}

在组件中使用自定义Hook

<template>
  <div>
    <h2>用户列表</h2>
    <div v-if="loading">加载中...</div>
    <ul v-if="data">
      <li v-for="user in data.users" :key="user.id">{{ user.name }}</li>
    </ul>
    <div v-if="error">{{ error.message }}</div>
  </div>

</template>

<script>
import { defineComponent } from 'vue';
import { useFetch } from './useFetch';

export default defineComponent({

  setup() {
    const { data, error, loading } = useFetch('https://api.example.com/users');

    return { data, error, loading };

  },

});

</script>

通过import导入useFetch,并在setup()函数中调用它,即在组件挂载后自动发起请求'api.example.com/users'。

React:

React 16 之前有三个生命周期阶段:挂载、更新和卸载。React 16 之后引入了新的生命周期方法。

1. 挂载阶段

constructor: 构造函数,在组件创建时调用。

componentWillMount (React 16 之前): 在组件即将被挂载到页面上时调用。

render: 渲染函数,在此函数中返回组件的虚拟 DOM。

componentDidMount: 组件已经被挂载到页面上后调用。

2. 更新阶段

componentWillReceiveProps (React 16 之前): 在组件接收到新的 props 之前调用。

shouldComponentUpdate: 在组件接收到新的 props 或者 state 时调用,用于判断是否重新渲染组件。

componentWillUpdate (React 16 之前): 在组件即将更新时调用。

render: 同上。

componentDidUpdate: 组件更新完成后调用。

3. 卸载阶段

componentWillUnmount: 在组件即将被卸载时调用。

4. 错误处理

componentDidCatch: 在子组件抛出错误后调用,用于捕获组件渲染期间发生的错误。

React类组件:

在react类组件中,可以显式的使用生命周期。

举例:

import React, { Component } from "react";

class MyComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }

  componentDidMount() {
    // 在组件挂载后,启动一个定时器,每秒更新一次 count 状态
    this.interval = setInterval(() => {
      this.setState({ count: this.state.count + 1 });
    }, 1000);
  }

  componentWillUnmount() {
    // 在组件卸载前清理定时器
    clearInterval(this.interval);
  }

  render() {
    return (
      <div>
        <h1>My Simple Component</h1>
        <p>Count: {this.state.count}</p>
      </div>
    );
  }
}

export default MyComponent;

React函数式组件:

React Hooks

React 开发中的主流更推荐函数式组件配合 React Hooks。除非对于某些复杂的场景,需要明确的更多的功能和生命周期方法。

而react的函数式组件之前没有生命周期方法。但是,从 React 16.8 版本开始,引入了 React Hooks,使得函数式组件也能够拥有类似生命周期的功能。通过useState useEffect useContext useCallback ,useRef useMemo等Hooks模拟生命周期行为,其调用和效果更为隐式。

这里重点举例useEffect

他是一个副作用钩子,替代componentDidMount 和 componentDidUpdate, shouldComponentUpdate,componentWillUnmount等生命周期,通过灵活运用useEffect,你可以模拟React类组件中大多数生命周期方法的行为。

它接受2个参数,第一个参数(必传)为一个执行callback函数,第二个参数(可选)是一个依赖数组。而参数不同,返回值不同时useEffect的使用场景也不同。

1. 当callback函数return一个清理函数,在组件卸载或下次渲染前(如果有依赖数组且依赖改变时),React会先调用这个返回的清理函数,避免造成内存泄漏或其他副作用

useEffect(async () => {
    if (text === 'hello World') {
      // 执行拉取数据
    }else{
      text=await getData();
    }
    
    // 可以return一个清理函数
    return () => {
      // 清理副作用:  比如取消订阅事件,清除定时器等
    }
  }, [text]);

2. 当没有return清理函数,且没有第二个参数(或者第二个参数为空数组)时,useEffect只会在第一次DOM挂载时执行一次,之后组件再重新渲染也不会执行。相当于执行一次的componentDidMount。

useEffect(() => {
    ...
    // 如果没有第二个参数或是空数组,表示只在组件挂载和卸载的时候执行一次
  },[]);

3. 当callback函数返回一个清理函数,并且没有第二个参数(或者第二个参数为空数组)时,相当于执行一次的componentDidMount和componentWillUnmount。

useEffect(async () => {
    if (text === 'hello World') {
      // 执行拉取数据
    }else{
      text=await getData();
    }

    // 可以return一个清理函数
    return () => {
      // 清理副作用:  比如取消订阅事件,清除定时器等
    }
  }, []);

4. 当第二个参数依赖数组不为空时,useEffect首次渲染后执行,之后每当依赖数组中的某个值发生变化时再次执行。相当于执行componentDidMount、componentDidUpdate和componentWillUnmount的组合行为。

useEffect(() => {

  console.log('componentDidUpdate 相关操作,仅当依赖项变化时执行');

}, [ValueA,ValueB]); // 依赖数组中的值变化时触发

结语:

感谢您花时间阅读这篇分享文章。希望通过这篇文章,您能对vue和react的生命周期钩子和hooks有了更深入的了解和认识。

转载自:https://juejin.cn/post/7376864081788485672
评论
请登录