Skip to content

Hook

https://zh-hans.reactjs.org/docs/hooks-intro.html

Hook 是 React 16.8 的新增特性
React Native 从 0.59 版本开始支持 Hook。

State Hook

这个例子用来显示一个计数器。当你点击按钮,计数器的值就会增加:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import React, { useState } from 'react';

function Example() {
  // 声明一个叫 “count” 的 state 变量。
  const [count, setCount] = useState(0);

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

在这里,useState 就是一个 Hook (等下我们会讲到这是什么意思)。
通过在函数组件里调用它来给组件添加一些内部 state。React 会在重复渲染时保留这个 state。
useState 会返回一对值:当前状态和一个让你更新它的函数,你可以在事件处理函数中或其他一些地方调用这个函数。
它类似 class 组件的 this.setState,但是它不会把新的 state 和旧的 state 进行合并。(我们会在使用 State Hook 里展示一个对比 useState 和 this.state 的例子)。

什么是 Hook?

Hook 是一些可以让你在函数组件里“钩入” React state 及生命周期等特性的函数。
Hook 不能在 class 组件中使用 —— 这使得你不使用 class 也能使用 React。

Hook 是一个特殊的函数,它可以让你“钩入” React 的特性。例如,useState 是允许你在 React 函数组件中添加 state 的 Hook。

Effect Hook

useEffect 就是一个 Effect Hook,给函数组件增加了操作副作用的能力。
它跟 class 组件中的 componentDidMount、componentDidUpdate 和 componentWillUnmount 具有相同的用途,只不过被合并成了一个 API。

例如,下面这个组件在 React 更新 DOM 后会设置一个页面标题:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import React, { useState, useEffect } from 'react';

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

  // 相当于 componentDidMount 和 componentDidUpdate:
  useEffect(() => {
    // 使用浏览器的 API 更新页面标题
    document.title = `You clicked ${count} times`;
  });

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

当你调用 useEffect 时,就是在告诉 React 在完成对 DOM 的更改后运行你的“副作用”函数。
由于副作用函数是在组件内声明的,所以它们可以访问到组件的 props 和 state。
默认情况下,React 会在每次渲染后调用副作用函数 —— 包括第一次渲染的时候。

如果想执行只运行一次的 effect(仅在组件挂载和卸载时执行),可以传递一个空数组([])作为第二个参数。
这就告诉 React 你的 effect 不依赖于 props 或 state 中的任何值,所以它永远都不需要重复执行。
这并不属于特殊情况 —— 它依然遵循依赖数组的工作方式。

自定义 Hook

https://zh-hans.reactjs.org/docs/hooks-custom.html

自定义 Hook 是一个函数,其名称以 “use” 开头,函数内部可以调用其他的 Hook。