react, hook, font end,

Hook:不必写Class就能使用React的功能

DolorHunter DolorHunter Follow Apr 11, 2021 · 49 mins read

Hook:不必写Class就能使用React的功能
Share this

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

React 大概有两种形式,Class/Function Component 和新加入的 Hook。其中,多数的 React 代码示例使用的都是 Class Component。最近在做毕设的时候,接触到了一个使用 Hook 的模板,因为之前看的文档基本都是 Class Component,前端接触的又不多,一度以为这是用 Function Component 写的,因为 Function Component 的资料少,还重写成了 Class。研究了以下文档 Hook 部分,才发现原来模板用的是 Hook。

注意:React 16.8.0 是第一个支持 Hook 的版本。升级时,请注意更新所有的 package,包括 React DOM。 React Native 从 0.59 版本开始支持 Hook。

Class Component

Class Component 大概长这样,整体的结构分为 state,componentDidMount 和 render 三部分。以下为一个简单示例。

import React, { Component } from "react";
import { Grid } from "@material-ui/core";
import MUIDataTable from "mui-datatables";

import axios from "axios";

export default class Tables extends Component {
  state = {
    datatableData: [],
    columns: [
      {
        name: "id",
        label: "ID",
        options: {
          display: "excluded",
        },
      },
      { name: "username", label: "用户名" },
      { name: "email", label: "邮箱" },
      { name: "phone", label: "电话" },
      { name: "createdDate", label: "注册日期" },
      { name: "isActivated", label: "状态" },
    ],
  };

  componentDidMount() {
    axios.post("/User/searchAllUserList", {}).then((res) => {
      if (res.status === 200 && Object.keys(res.request.response).length > 0) {
        const datatableData = JSON.parse(res.request.response);
        this.setState({ datatableData });
      }
    });
  }

  render() {
    return (
      <>
        <Grid container spacing={4}>
          <Grid item xs={12}>
            <MUIDataTable
              title="用户列表"
              data={this.state.datatableData}
              columns={this.state.columns}
              options=
            />
          </Grid>
        </Grid>
      </>
    );
  }
}

Hook

Hook 的写法虽然也是类似的三部分,但是更加灵活。相同意义的部件用 Hook 写长这样。

import React, { useState, useEffect } from "react";
import { Grid } from "@material-ui/core";
import MUIDataTable from "mui-datatables";

import axios from "axios";

export default function Tables(props) {
  var [datatableData, setdatatableData] = useState([]);
  var [columns, setColumns] = useState([
    {
      name: "id",
      label: "ID",
      options: {
        display: "excluded",
      },
    },
    { name: "username", label: "用户名" },
    { name: "email", label: "邮箱" },
    { name: "phone", label: "电话" },
    { name: "createdDate", label: "注册日期" },
    { name: "isActivated", label: "状态" },
  ]);

  useEffect(() => {
    axios.post("/User/searchAllUserList", {}).then((res) => {
      if (res.status === 200 && Object.keys(res.request.response).length > 0) {
        const data = JSON.parse(res.request.response);
        setdatatableData(data);
      }
    });
  }, []);

  return (
    <>
      <Grid container spacing={4}>
        <Grid item xs={12}>
          <MUIDataTable
            title="用户列表"
            data={this.state.datatableData}
            columns={this.state.columns}
            options=
          />
        </Grid>
      </Grid>
    </>
  );
}

Hook的意义

Hook可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。比如可以通过set完成变量赋值,通过useEffect的[]完成数据更新。基本上Class能实现的,Hook也能实现。

根据 Hook简介-动机 中的描述:

  1. 由 providers,consumers,高阶组件,render props 等其他抽象层组成的组件会形成“嵌套地狱”。

  2. 同一个 componentDidMount 中可能也包含很多其它的逻辑,在多数情况下,不可能将组件拆分为更小的粒度,使得复用变得更加困难。

  3. class 是学习 React 的一大屏障.即便在有经验的 React 开发者之间,对于函数组件与 class 组件的差异也存在分歧。

Hook的import包含了React和useState, useEffect两部分,而Component包含React和Component。useState是用来做初始状态赋值的,useEffect是来做数据更新的。

其中 useEffect(() => {}, []);[] 中的内容为动态更新的变量内容(为空的话就不更新)。React会根据 [] 中的数据是否更新,来判断是否渲染新的内容(会一直发送axios请求)。如果不写 [] 的话,就会一直执行useEffect的内容,此时网页应该会卡飞。

如果你在编写函数组件并意识到需要向其添加一些 state,以前的做法是必须将其转化为 class。现在你可以在现有的函数组件中使用 Hook。

不过我目前只有体会到Hook的使用方便,例如把function形式代码改写为Hook变得更加容易。对于嵌套和状态,有遇过一次使用多个react(把hook改写为class),但是暂时还没有什么理解。当下只是觉得很郁闷,查了半天也不太清楚要怎么改错。Hook对我来说就是一种更好的Class,可以很轻易完成新的模块的加入,并且不用担心会出问题。

参考资料:

Join Newsletter
Get the latest news right in your inbox. We never spam!
DolorHunter
Written by DolorHunter
Developer & Independenet Blogger