React hooks的优缺点详解

 更新时间:2021年04月26日 08:26:27   作者:ranyonsue  
这篇文章主要介绍了React hooks的优缺点详解,帮助大家更好的理解和学习使用React,感兴趣的朋友可以了解下

前言

Hook 是 React 16.8 的新增特性。它是完全可选的,并且100%向后兼容。它可以让你使用函数组件的方式,运用类组件以及 react 其他的一些特性,比如管理状态、生命周期钩子等。从概念上讲,React 组件一直更像是函数。而 Hook 则拥抱了函数,同时也没有牺牲 React 的精神原则。

优点:

1、代码可读性更强,原本同一块功能的代码逻辑被拆分在了不同的生命周期函数中,容易使开发者不利于维护和迭代,通过 React Hooks 可以将功能代码聚合,方便阅读维护。例如,每个生命周期中常常会包含一些不相关的逻辑。一般我们都会在 componentDidMount 和 componentDidUpdate 中获取数据。但是,同一个 componentDidMount 中可能也包含很多其它的逻辑,如设置事件监听,而之后需在 componentWillUnmount 中清除。相互关联且需要对照修改的代码被进行了拆分,而完全不相关的代码却在同一个方法中组合在一起。如此很容易产生 bug,并且导致逻辑不一致。
2、组件树层级变浅。在原本的代码中,我们经常使用 HOC/render props 等方式来复用组件的状态,增强功能等,无疑增加了组件树层数及渲染,在 React DevTools 中观察过 React 应用,你会发现由 providers,consumers,高阶组件,render props 等其他抽象层组成的组件会形成“嵌套地狱”。而在 React Hooks 中,这些功能都可以通过强大的自定义的 Hooks 来实现。
3、不用再去考虑 this 的指向问题。在类组件中,你必须去理解 JavaScript 中 this 的工作方式。

缺点:

一、响应式的useEffect

写函数组件时,你不得不改变一些写法习惯。你必须清楚代码中useEffect和useCallback的“依赖项数组”的改变时机。有时候,你的useEffect依赖某个函数的不可变性,这个函数的不可变性又依赖于另一个函数的不可变性,这样便形成了一条依赖链。一旦这条依赖链的某个节点意外地被改变了,你的useEffect就被意外地触发了,如果你的useEffect是幂等的操作,可能带来的是性能层次的问题,如果是非幂等,那就糟糕了。

所以,对比componentDidmount和componentDidUpdate,useEffect带来的心智负担更大。

二、状态不同步

函数的运行是独立的,每个函数都有一份独立的作用域。函数的变量是保存在运行时的作用域里面,当我们有异步操作的时候,经常会碰到异步回调的变量引用是之前的,也就是旧的(这里也可以理解成闭包)。比如下面的一个例子:

import React, { useState } from "react";
​
const Counter = () => {
  const [counter, setCounter] = useState(0);
​
  const onAlertButtonClick = () => {
    setTimeout(() => {
      alert("Value: " + counter);
    }, 3000);
  };
​
  return (
    <div>
      <p>You clicked {counter} times.</p>
      <button onClick={() => setCounter(counter + 1)}>Click me</button>
      <button onClick={onAlertButtonClick}>
        Show me the value in 3 seconds
      </button>
    </div>
  );
};
​
export default Counter;

当你点击Show me the value in 3 seconds的后,紧接着点击Click me使得counter的值从0变成1。三秒后,定时器触发,但alert出来的是0(旧值),但我们希望的结果是当前的状态1。

这个问题在class component不会出现,因为class component的属性和方法都存放在一个instance上,调用方式是:this.state.xxx和this.method()。因为每次都是从一个不变的instance上进行取值,所以不存在引用是旧的问题。

其实解决这个hooks的问题也可以参照类的instance。用useRef返回的immutable RefObject(current属性是可变的)来保存state,然后取值方式从counter变成了: counterRef.current。如下:

import React, { useState, useRef, useEffect } from "react";
​
const Counter = () => {
  const [counter, setCounter] = useState(0);
  const counterRef = useRef(counter);
​
  const onAlertButtonClick = () => {
    setTimeout(() => {
      alert("Value: " + counterRef.current);
    }, 3000);
  };
​
  useEffect(() => {
    counterRef.current = counter;
  });
​
  return (
    <div>
      <p>You clicked {counter} times.</p>
      <button onClick={() => setCounter(counter + 1)}>Click me</button>
      <button onClick={onAlertButtonClick}>
        Show me the value in 3 seconds
      </button>
    </div>
  );
};
​
export default Counter;

结果我们所期待,alert的是当前的值1。

怎么避免react hooks的常见问题

  • 不要在useEffect里面写太多的依赖项,划分这些依赖项成多个单一功能的useEffect。其实这点是遵循了软件设计的“单一职责模式”。
  • 如果你碰到状态不同步的问题,可以考虑下手动传递参数到函数。如:
   // showCount的count来自父级作用域 
   const [count,setCount] = useState(xxx); 
   function showCount(){ console.log(count) } 

   // showCount的count来自参数 
   const [count,setCount] = useState(xxx); 
   function showCount(c){ console.log(c) }

但这个也只能解决一部分问题,很多时候你不得不使用上述的useRef方案。

3. 重视eslint-plugin-react-hooks插件的警告。

4. 复杂业务的时候,使用Component代替hooks。

以上就是React hooks的优缺点详解的详细内容,更多关于React hooks的优缺点的资料请关注脚本之家其它相关文章!

相关文章

  • React路由管理之React Router总结

    React路由管理之React Router总结

    React项目通常都有很多的URL需要管理,最常使用的解决方案就是React Router了,本篇文章主要介绍了React路由管理之React Router总结,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • 使用hooks写React组件需要注意的5个地方

    使用hooks写React组件需要注意的5个地方

    这篇文章主要介绍了使用hooks写React组件需要注意的5个地方,帮助大家更好的理解和学习使用React组件,感兴趣的朋友可以了解下
    2021-04-04
  • 浅谈React前后端同构防止重复渲染

    浅谈React前后端同构防止重复渲染

    这篇文章主要介绍了浅谈React前后端同构防止重复渲染,首先解释React前后端同构、React首屏渲染的概念。然后通过这2个概念解决服务端渲染完成后浏览器端重复渲染的问题。有兴趣的可以了解一下
    2018-01-01
  • React Native自定义控件底部抽屉菜单的示例

    React Native自定义控件底部抽屉菜单的示例

    本篇文章主要介绍了React Native自定义控件底部抽屉菜单的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • 详解使用React全家桶搭建一个后台管理系统

    详解使用React全家桶搭建一个后台管理系统

    本篇文章主要介绍了使用React全家桶搭建一个后台管理系统,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • 基于react hooks,zarm组件库配置开发h5表单页面的实例代码

    基于react hooks,zarm组件库配置开发h5表单页面的实例代码

    这篇文章主要介绍了基于react hooks,zarm组件库配置开发h5表单页面,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • react native 文字轮播的实现示例

    react native 文字轮播的实现示例

    这篇文章主要介绍了react native 文字轮播的实现示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-07-07
  • react native环境安装流程

    react native环境安装流程

    React Native 是目前流行的跨平台移动应用开发框架之一。本文介绍react native环境安装流程及遇到问题解决方法,感兴趣的朋友一起看看吧
    2021-05-05
  • D3.js(v3)+react 实现带坐标与比例尺的柱形图 (V3版本)

    D3.js(v3)+react 实现带坐标与比例尺的柱形图 (V3版本)

    这篇文章主要介绍了D3.js(v3)+react 制作 一个带坐标与比例尺的柱形图 (V3版本) ,本文通过实例代码文字相结合的形式给大家介绍的非常详细,需要的朋友可以参考下
    2019-05-05
  • 详解React Hooks是如何工作的

    详解React Hooks是如何工作的

    React Hooks是在React 16.8版本新增的特性,在我看了React官网和一些博客对React Hook的讲解后还是觉得没有get到本质。本篇博客通过手动实现useState()来了解Hook的原理和本质。阅读此篇博客的前提是你要知道一些 React Hooks的基本用法和使用规则,不然会看得云里雾里。
    2021-05-05

最新评论