Hooks核心02

新思想的开始很重要

如果已经习惯了类组件的开发,那么要做的,甚至是彻底忘掉那些生命周期方法。不要遇到一个需求,就映射到这个功能该在哪个生命周期中去做,然后又要去想原来的声明周期方法在函数组件中应该怎么用 Hooks 去实现。
正确的思路应该是遇到需求时,直接考虑在 Hooks 中去如何实现

useState:让函数组件具有维持状态的能力

原则:state 中永远不要保存可以通过计算得到的值

  1. 通过 props 传递过来的值
  2. 从 URL 中读到的值。
  3. 从 cookie、localStorage 中读取的值。

useEffect:执行副作用

什么是副作用?

通常来说,副作用是执行与当前结果无关的代码。比如说要修改函数外部的某个变量,要发起一个请求,等等。也就是说,在函数组件的当次执行过程中,useEffect 中代码的执行是不影响渲染出来的 UI 的。

useEffect 让我们能够在下面四种时机去执行一个回调函数产生副作用:

  1. 每次 render 后执行:不提供第二个依赖项参数。比如 useEffect(() => {})。
  2. 仅第一次 render 后执行:提供一个空数组作为依赖项。比如 useEffect(() => {}, [])。
  3. 第一次以及依赖项发生变化后执行:提供依赖项数组。比如 useEffect(() => {}, [deps])。
  4. 组件 unmount 后执行:返回一个回调函数。比如 useEffect() => { return () => {} }, [])。

理解 Hooks 的依赖

Hooks 提供了让你监听某个数据变化的能力。这个变化可能会触发组件的刷新,也可能是去创建一个副作用,又或者是刷新一个缓存。那么定义要监听哪些数据变化的机制,其实就是指定 Hooks 的依赖项

定义依赖项的注意点:

  1. 依赖项中定义的变量一定是会在回调函数中用到的,否则声明依赖项其实是没有意义的。
  2. 依赖项一般是一个常量数组,而不是一个变量。因为一般在创建 callback 的时候,你其实非常清楚其中要用到哪些依赖项了。
  3. React 会使用浅比较来对比依赖项是否发生了变化,所以要特别注意数组或者对象类型。如果你是每次创建一个新对象,即使和之前的值是等价的,也会被认为是依赖项发生了变化。(每次重新渲染函数,依赖项的地址发生的变化)

掌握 Hooks 的使用规则

Hooks 本身作为纯粹的 JavaScript 函数,不是通过某个特殊的 API 去创建的,而是直接定义一个函数,所以需要遵循一定的规则才能正常的工作。

使用规则如下:

  1. 在 useEffect 的回调函数中使用的变量,都必须在依赖项中声明;
  2. Hooks 不能出现在条件语句或者循环中,也不能出现在 return 之后;
  3. Hooks 只能在函数组件或者自定义 Hooks 中使用。

class 组件就不能使用 hooks 了吗?

利用高阶组件的模式,将 Hooks 封装成高阶组件,从而让类组件使用。

import React from "react"
import { useWindowSize } from "../hooks/useWindowSize"

const withWindowSize = Component => {
  return props => {
    const windowSize = useWindowSize()
    return <Component windowSize={windowSize} {...props} />
  }
}

class MyComponent {
  render() {
    const { windowSize } = this.props
    // ...
  }
}

// 通过 withWindowSize 高阶组件给 MyComp 添加 windowSize 属性
export default withWindowSize(MyComponent)

Published under  on .

pipihua

我是皮皮花,一个前后端通吃的前端攻城狮,如果感觉不错欢迎点击小心心♥(ˆ◡ˆԅ) star on GitHub!