Vue和React对比学习之Hooks

不知道大家有没有发现随着版本的升级 vue 和 react 越来越像了。

2019年年初,react 在 16.8.x 版本正式具备了 hooks 能力。

2019年6月,尤雨溪提出了关于 vue3 Component API 的提案。笔者理解这其实是 vue 版本的 hooks

Vue 和 React 相继都推出了Hooks,那么今天我们就通过对比的方式来学习 Vue 和 React 的 Hook

为什么需要 Hooks

使在组件之间复用状态逻辑更简单

vue中我们使用mixinsextends来复用逻辑,在react中可以使用render props 或者 HOC来复用逻辑。但是它们都会有弊端。

比如vue中的mixins,当我们一个组件引入很多mixin的时候,多个mixin的同名、合并等问题随之而来,而且也不利于我们代码理解和问题排查。

比如react中的render props 或者 HOC,传递渲染属性和高阶组件的层层嵌套包裹,也不利于代码的理解和维护。

这个时候Hook就能很好的解决了

Hook 使你在无需修改组件结构的情况下复用状态逻辑。 这使得在组件间或社区内共享 Hook 变得更便捷。

让相关代码聚合在一起

vue2版本的时候,我们的一个简单业务代码会分得很散,比如data定义了数据,methods里面定义了方法,生命周期函数里面又做了处理等等。代码就会很分散,不利于维护和阅读。所以vue3就推出了composition api。这样让相关逻辑代码聚合在一起。

react class组件也有类似问题,一个简单业务代码会分得很散,可能state定义在constructor里面,生命周期函数里面又做了处理等等。代码就会很分散,不利于维护和阅读。hooks的推出让相关逻辑代码聚合在一起,代码能更好的阅读和维护了。

Hooks带来的好处是显而易见的: “高度聚合,可阅读性提升” 。伴随而来的便是 “效率提升,bug变少” 。

让组件更容易理解

这里重点说下this

vue2里面this可能还好点,都是指向当前vue实例,但是react class组件里面经常需要处理一些this问题,比如函数要bind(this)等。

但在Hooks 写法中,你就完全不必担心 this 的问题了。Hooks 写法直接告别了 this 问题。

副作用的关注点分离

副作用指那些没有发生在数据向视图转换过程中的逻辑,如 ajax 请求、访问原生dom 元素、本地持久化缓存、绑定/解绑事件、添加订阅、设置定时器、记录日志等

以往这些副作用都是写在类组件生命周期函数中的。

在react中,我们可以使用 useEffectuseLayoutEffect来替代类组件生命周期函数。useEffect 在全部渲染完毕后才会执行,useLayoutEffect 会在浏览器 layout 之后,painting 之前执行。

 

自定义Hook

通过自定义 Hook,可以将组件逻辑提取到可重用的函数中。ReactVue都支持自定义Hook

下面我们分别用ReactVue实现一个实现鼠标打点的自定义 Hook

React

React自定义Hook不管内置Hook还是自定义Hook都必须以use开头。

import { useEffect, useState } from "react";

const usePoint = () => {
  const [point, setPointe] = useState({ x: 0, y: 0 });

  const savePoint = (e) => {
    setPointe({ x: e.pageX, y: e.pageY });
  };

  useEffect(() => {
    window.addEventListener("click", savePoint);

    return () => {
      window.removeEventListener("click", savePoint);
    };
  }, []);

  return point;
};

function CustomHook() {
  const point = usePoint();
  return (
    <div>
      <div>
        x: {point.x} y: {point.y}
      </div>
    </div>
  );
}

export default CustomHook;

Vue

Vue 自定义Hook 没有强制规则,随意。

// hook/point.js

import { reactive, onMounted, onBeforeUnmount } from "vue";

export default function() {
    //保存鼠标“打点”相关的数据
    let point = reactive({
        x: 0,
        y: 0,
    });

    //实现鼠标“打点”相关的方法
    function savePoint(event) {
        point.x = event.pageX;
        point.y = event.pageY;
    }

    //实现鼠标“打点”相关的生命周期钩子
    onMounted(() => {
        window.addEventListener("click", savePoint);
    });

    onBeforeUnmount(() => {
        window.removeEventListener("click", savePoint);
    });

    return point;
}

使用

<template>
<h2>当前点击时鼠标的坐标为:x:{{point.x}},y:{{point.y}}</h2>
</template>

<script>
import usePoint from '../hook/point.js'
export default {
  name:'CustomHook',
  setup(){
    const point = usePoint()
    return {point}
  }
}
</script>

这在vue2,如果想要实现这样一个功能是不是需要创建一个vue组件然后引用过来使用呢?因为vue2生命周期没办法在普通js中使用,响应式data也没办法在普通js函数中使用。

但在vue3这一切都可以实现,我们直接创建一个自定义Hook就能复用逻辑,类似一个组件,是不是很好用呢。(vue3的定义响应式数据、生命周期函数、watch监听等方法都能在普通js中使用,大大提高了复用效率。)

总结

相同点

  1. 总体思路是一致的 都遵照着 "定义状态数据","操作状态数据","隐藏细节" 作为核心思路。
  2. 都是为了能更好的复用逻辑、让相关代码聚合在一起、更好的代码理解。

不同点

  1. vue3 的组件里, setup 是作为一个早于 created 的生命周期存在的,无论如何,在一个组件的渲染过程中只会进入一次。React函数组件 则完全不同,如果没有被 memorized,它们可能会被不停地触发,不停地进入并执行方法,因此上手难度相较于Vue来说要大一点。

 

参考

https://zhuanlan.zhihu.com/p/571715690

 

转载自

https://juejin.cn/post/7103010557736779789#heading-1

posted @   泠风lj  阅读(118)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示