资讯专栏INFORMATION COLUMN

使用React Hook提高代码复用性

KevinYan / 3292人阅读

摘要:看完代码应该就能很好的理解的使用了吧,具体代码的运行点击在线演示查看在线演示总结给我们带来的就是在函数的基础上可以加入状态和生命周期等函数不曾有的特性,这个特性的加入能够让我们更好的抽象组件,提高代码的复用性。

Hook 简介

Hook 是 React 16.8 的新增特性。是对 React 函数组件的一种扩展,通过提供一些特殊的函数,让无状态的组件拥有状态组件才拥有的能力。

没有Hook之前写组件有两种形式,分别为

函数组件

class组件

函数组件特点如下

所有的数据都是依赖props传入的,没有内部state

没有生命周期

没有this(组件实例)

实际开发中因为业务复杂,一般使用函数组件无法满足,所以大家默认都是使用class组件进行开发,这是一个不会出错的选择。函数组件大家平时应该都挺少会去用的,因为函数组件能提供的功能比较局限。但是引入Hook后,函数的能力就被扩展了许多,因为函数的特性,非常适合抽象成可复用的组件。

解决哪些问题 不同组件间与状态有关的逻辑复用问题

平时写组件的方式就是通过props传递给下一个组件,有些简单的情况这样也挺好的。但是当项目不断迭代,会发现当组件被多个模块多次引用,还是会多写一些重复的逻辑。因为受到到状态或者生命周期的影响,导致这部分逻辑却又很难拆出来。

引入Hook就可以将受状态或生命周期影响的组件抽出来。

业务发展导致组件日益庞大

最外层的代码集中维护许多state状态,导致页面引入越来越多毫无关联的模块,代码的可读性大大降低,有时候因为多个生命周期里面有大量不相关的逻辑,这样杂乱的代码容易引起bug,也增加了其它开发人员维护的难度。

Hook将组件中每一个相关的小模块拆分成一个函数,这样能够让组件即使庞大结构也是清晰的。

用法

State Hook: 在函数组件中使用state

Effect Hook: 在函数组件中使用生命周期

Custom Hook: 自定义Hook,可以将组件逻辑提取到函数中。(注意:自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 Hook)

Hook 规则

Hook 本质就是 JavaScript 函数,但是在使用它时需要遵循两条规则

只在最顶层使用 Hook(不要在循环,条件或嵌套函数中调用)

只在 React 函数中调用 Hook

ESLint 插件

强制执行 hooks 的最佳实践

eslint-plugin-react-hooks

如何使用

详细的一些概念官方文档已经写得很全面了,可以参考:Hook的官方文档。

接下来就用一个实际的例子来说明一下State Hook的使用

示例

产品第一版本需求如下:

现在有 小A,小B 两位同学,每位同学都处于未穿鞋的状态,小A穿鞋需要2s,小B穿鞋需要5s,在页面一中用文字描述两位同学的穿鞋状态变更( 如果小A正在穿鞋中,则在页面上显示 "小A正在穿鞋子",如果小A已经穿好了鞋子,则将文字替换为 "小A已经穿好鞋子")

使用class组件实现如下:

src/demo1.js

import React from "react";

class Page extends React.Component {
  state = {
    data: [
      { id: 1, name: "小A", time: "2000" },
      { id: 2, name: "小B", time: "5000" }
    ]
  };

  start(item) {
    this.setState({
      [item.id]: "穿鞋子"
    });

    setTimeout(() => {
      this.setState({
        [item.id]: "穿好鞋子"
      });
    }, item.time);
  }

  componentDidMount() {
    this.state.data.forEach(item => {
      this.start(item);
    });
  }

  render() {
    return (
      
{this.state.data.map(item => { return (

{this.state[item.id] === "穿鞋子" ? `${item.name}正在穿鞋子...` : `${item.name}已经穿好鞋子了`}

); })}
); } } export default Page;

使用Hook组件实现如下:

自定义hook如下:

src/useHook.js

import React, { useState } from "react";

function useHook(item) {
  const [status, setStatus] = useState("穿鞋子");

  setTimeout(() => {
    setStatus("穿好鞋子");
  }, item.time);

  return (
    

{status === "穿鞋子" ? `${item.name}正在穿鞋子...` : `${item.name}已经穿好鞋子了`}

); } export default useHook;

引用hook的函数组件

src/hookDemo1.js

import React from "react";
import useHook from "./useHook";

function Page() {
  const data = [
    { id: 1, name: "小A", time: "2000" },
    { id: 2, name: "小B", time: "5000" }
  ];
  return (
    
{data.map(item => { return useHook(item); })}
); } export default Page;

好了,实现完上面的需求,现在觉得hook的好处并没有什么体现,接下来产品又发布了第二版需求,要求我们在另一个页面显示另外两位同学的状态。需求如下:

现在有 小C,小D 两位同学,每位同学都处于未穿鞋的状态,小A穿鞋需要4s,小B穿鞋需要8s,在页面二中用文字描述两位同学的穿鞋状态变更( 如果小A正在穿鞋中,则在页面上显示 "小C正在穿鞋子",如果小C已经穿好了鞋子,则将文字替换为 "小C已经穿好鞋子")

接下来再第一个版本的基础上来实现第二个需求

使用class组件实现如下:

src/demo2.js

import React from "react";

class Page extends React.Component {
  state = {
    data: [
      { id: 1, name: "小C", time: "4000" },
      { id: 2, name: "小D", time: "8000" }
    ]
  };

  start(item) {
    this.setState({
      [item.id]: "穿鞋子"
    });

    setTimeout(() => {
      this.setState({
        [item.id]: "穿好鞋子"
      });
    }, item.time);
  }

  componentDidMount() {
    this.state.data.forEach(item => {
      this.start(item);
    });
  }

  render() {
    return (
      
{this.state.data.map(item => { return (

{this.state[item.id] === "穿鞋子" ? `${item.name}正在穿鞋子...` : `${item.name}已经穿好鞋子了`}

); })}
); } } export default Page;

使用Hook组件实现如下:

src/hookDemo2.js

import React from "react";
import useHook from "./useHook";

function Page() {
  const data = [
    { id: 1, name: "小C", time: "4000" },
    { id: 2, name: "小D", time: "8000" }
  ];
  return (
    
{data.map(item => { return useHook(item); })}
); } export default Page;

第二次的代码明显比第一次少了许多,而且如果之后产品如果增加了一个状态,那明显使用Hook实现的方式可以更快的适应需求的变更,代码的维护性也变高了许多。

看完代码应该就能很好的理解hook的使用了吧,具体代码的运行点击在线演示查看

在线演示

总结

Hook给我们带来的就是在函数的基础上可以加入状态和生命周期等函数不曾有的特性,这个特性的加入能够让我们更好的抽象组件,提高代码的复用性。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104086.html

相关文章

  • React Hooks入门: 基础

    摘要:当组件安装和更新时,回调函数都会被调用。好在为我们提供了第二个参数,如果第二个参数传入一个数组,仅当重新渲染时数组中的值发生改变时,中的回调函数才会执行。 前言   首先欢迎大家关注我的Github博客,也算是对我的一点鼓励,毕竟写东西没法获得变现,能坚持下去也是靠的是自己的热情和大家的鼓励,希望大家多多关注呀!React 16.8中新增了Hooks特性,并且在React官方文档中新增...

    mrli2016 评论0 收藏0
  • React Hook 不完全指南

    摘要:使用完成副作用操作,赋值给的函数会在组件渲染到屏幕之后。如此很容易产生,并且导致逻辑不一致。同时,这也是很多人将与状态管理库结合使用的原因之一。当我们通过的第二个数组类型参数,指明当前的依赖,就能避免不相关的执行开销了。 前言 本文内容大部分参考了 overreacted.io 博客一文,同时结合 React Hook 官方 文章,整理并归纳一些笔记和输出个人的一些理解 什么是 Hoo...

    Lin_R 评论0 收藏0
  • React Hook起飞指南

    摘要:起飞指南作者元潇方凳雅集出品目前放出来了个内置,但仅仅基于以下两个,就能做很多事情。行代码实现一个全局元潇根组件挂上即可子组件调用随时随地实现一个局部元潇的本质是的一个语法糖,感兴趣可以阅读一下的类型定义和实现。 React Hook起飞指南 作者:元潇 方凳雅集出品 16.8目前放出来了10个内置hook,但仅仅基于以下两个API,就能做很多事情。所以这篇文章不会讲很多API,...

    姘搁『 评论0 收藏0
  • 浅谈React Hooks

    摘要:另外也不利于组件的,及。所以在使用时,尽量将相关联的,会共同变化的值放入一个。有同学可能会想,每次后都会执行,这样会不会对性能造成影响。另外必须以开头来命名,这样工具才能正确检测其是否符合规范。 由于工作的原因我已经很长时间没接触过React了。前段时间圈子里都在讨论React Hooks,出于好奇也学习了一番,特此整理以加深理解。 缘由 在web应用无所不能的9012年,组成应用的C...

    yearsj 评论0 收藏0
  • React-hooks 简介

    摘要:比如在条件判断中使用,在循环,嵌套函数中使用,都会造成执行顺序不一致的问题。而比如定时器,事件监听。第一个参数的返回值,会在组件卸载时执行,相当于,可以清理定时器,移除事件监听,取消一些订阅。 什么是 Hooks? 不通过编写类组件的情况下,可以在组件内部使用状态(state) 和其他 React 特性(生命周期,context)的技术 Hooks 为什么会出现 在之前的 React ...

    incredible 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<