阅读 987

React Hooks 的用法

最近在写React项目的时候遇到了一些state logic重用的问题,由于react里面对于state的定义是组件的生命周期只存在与组件自身内,如果要实现组件与组件之前的通信,传统的做法是通过将组件交互的那一部分state代码上升到共同的parent组件上去,在parent里面定义一些实现状态改变的方法,然后通过props的方式传递下去,这样的做法虽然很合理,但是不太适合有着复杂层级关系的项目,后来就有了redux这个状态管理机制来统一管理组件的状态,将共用的状态抽离出来放在一个store里面统一管理,通过dispatch action的方式映射到reduce里面相应的actionType 来实现state的更新,这样虽然很好的管理了状态的变化,但是有一个问题还是没有解决,那就是组件的state 逻辑的重用,说到这里就要讲到一个新概念 Hooks,这个是在React 16.8.0版本后提出的一个新概念。 

Hooks的背景

It’s essentially a way to create components with features, like state, without the need for class components.

以上是react官方对于hooks的解释,简单点说就是用了hooks后,不需要创建类组件了,传统的无状态函数式组件搭载了hooks就可以实现类组件的生命周期以及状态的管理,更牛逼的是状态管理的逻辑可以重用, 听起来是不是很酷炫狂拽吊炸天。 

Hooks

 A Hook is a special function that lets you “hook into” React features. For example, useState is a Hook that lets you add React state to function components. We’ll learn other Hooks later. 

React官方已经定了一些内置的hooks,在这里我就不一一介绍了,今天我主要介绍两个常用的hooks, useState, useEffect

useState

import React, { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);复制代码

废话不多说,先撸代码,useState是一个方法,该方法只接受一个参数 initState, 该参数可以任意一种数据类型(number, string, object , boolean 等) 

该方法返回一个长度为2的数组,数组第一个是值状态值,数组第二个值是改变状态值的方法,具体关于方法的命名规范,请参考React的文档 Use the State Hook  例子中 setCount方法就类似于setState的方法,状态的修改会触发组件的re-render。 

useEffect 

By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates. In this effect, we set the document title, but we could also perform data fetching or call some other imperative 
import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  // Similar to componentDidMount and componentDidUpdate:
  useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}复制代码

由于引进了hooks后,React不在依赖于定义类组件来实现生命周期,现在只需 import useEffect方法即可实现对应状态的生命周期管理,并且不局限于某个特定的class,而是针对于某个或多个特定的状态的生命周期管理,具体关于useEffect的使用,请参考官网Using the Effect Hooks  

⚠️: useEffect方法在每次组件重新渲染的时候 默认情况下会执行的,但是你可以设置它的执行规则 (可以设置只执行一次),具体参考 Using the Effect Hooks

自定义hooks, 

这一部分是最关键了,我们可以定义自己的hooks 轮子。what's more, 可以分享定义的轮子并让其他开发者去使用, 个人觉得这是hook给react开发带来的里程碑式的改变,那how to自定义一个hook呢,这一部分其实很简单,只需定一个hook 函数, 并引入useState, useEffect 等方法来管理状态,将需要重用的状态逻辑抽离出来封装到自定义的hook方法里。 具体如何实现,大家可以参考一下我的github react-hooks , 另外欢迎大家review我的code,并提出一些issues 🙏。 大家可以看一下我那个demo 的github pages ,具体demo页面功能👇


总结: 

hooks 帮助摆脱定义繁琐的class 组件的束缚,同时封装可重用的自定义hooks的逻辑。 

useState, useEffect 等内置的hooks来帮助创造hooks的生态圈,实现state 逻辑的跨组件共享。 

⚠️踩过的坑:在项目里面如果在不同的组件里面都引用同样的hook, 该hook里面定义的state并不会共享,而是相互独立的,这一点大家自己测试一下。这一部分是由于JS闭包所导致。


第一次写技术文档,希望各位大咖多给点建议,feedback is always important for improvement.  如果大家觉得我这个react-hooks demo写的不错的话,大家给个star吧😂,如果大家觉得写的不好,也欢迎大家给在issues里面给反馈😄。