运用React Hook进步代码复用性

Hook 简介

Hook 是 React 16.8 的新增特征。是对 React 函数组件的一种扩大,经由过程供应一些特别的函数,让无状况的组件具有状况组件才具有的才能。

没有Hook之前写组件有两种情势,分别为

  • 函数组件
  • class组件

函数组件特性以下

  1. 一切的数据都是依靠props传入的,没有内部state
  2. 没有生命周期
  3. 没有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 (
      <div>
        {this.state.data.map(item => {
          return (
            <h1 key={item.id}>
              {this.state[item.id] === "穿鞋子"
                ? `${item.name}正在穿鞋子...`
                : `${item.name}已穿好鞋子了`}
            </h1>
          );
        })}
      </div>
    );
  }
}

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 (
    <h1 key={item.id}>
      {status === "穿鞋子"
        ? `${item.name}正在穿鞋子...`
        : `${item.name}已穿好鞋子了`}
    </h1>
  );
}

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 (
    <div>
      {data.map(item => {
        return useHook(item);
      })}
    </div>
  );
}

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 (
      <div style={{ color: "lightblue" }}>
        {this.state.data.map(item => {
          return (
            <h1 key={item.id}>
              {this.state[item.id] === "穿鞋子"
                ? `${item.name}正在穿鞋子...`
                : `${item.name}已穿好鞋子了`}
            </h1>
          );
        })}
      </div>
    );
  }
}

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 (
    <div style={{ color: "lightblue" }}>
      {data.map(item => {
        return useHook(item);
      })}
    </div>
  );
}

export default Page;

第二次的代码显著比第一次少了很多,而且假如以后产物假如增加了一个状况,那显著运用Hook完成的体式格局能够更快的顺应需求的变动,代码的保护性也变高了很多。

看完代码应当就可以很好的明白hook的运用了吧,详细代码的运转点击在线演示检察

在线演示

总结

Hook给我们带来的就是在函数的基本上能够到场状况和生命周期等函数未曾有的特征,这个特征的到场能够让我们更好的笼统组件,进步代码的复用性。

    原文作者:niceartisan
    原文地址: https://segmentfault.com/a/1190000019067303
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞