blog icon indicating copy to clipboard operation
blog copied to clipboard

React Hooks 总结

Open ly2011 opened this issue 7 years ago • 0 comments

什么是 Hooks?

Hooks是一个在React函数组件内一类特殊的函数(通常以 "use" 开头,比如 "useState"),使开发者能够在 function component里依旧使用 state 和 life-cycles,以及使用 custom hook 复用业务逻辑。

Hook在 类的内部不起作用

动机

class component模式有如下一些缺点:

  • 组件间交流的耦合度很高,组件树臃肿
  • JavaScript的class产生的诸多疑惑

Hooks的规则

Hooks是JavaScript方法,但它们增加了两个额外的规则:

  • 只能在顶层调用 Hooks,不能在循环、条件或者嵌套方法中调用 Hooks。
  • 仅在React功能组件中使用 Hooks。不能在常规的JavaScript中调用Hooks。

Write Hooks

Hooks 主要分为三种

  • State hooks (在function component 中使用 state)
  • Effect hooks(在function component 中使用 生命周期 和 side effect)
  • Custom hooks(自定义 hooks 用来复用组件逻辑,解决了上述的第一个动机中阐述的问题)

State hooks

import { useState } from 'react';

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

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

之前讲过 hook 本质是一个特殊的函数(通常以 "use" 开头)。在这里,"useState" 就是一个 hook,通过它我们能够嵌入组件内部的 state。这个函数返回一个 pair,第一个值是当前对应这个 hook 的 state 值,第二个是怎样更新这个值。

我们可以从中感觉到,这两个返回值分别对应的以前的用法是:

  • this.state
  • this.setState

除此之外,我们还可以在一个函数组件中使用多个 useState:

function ExampleWithManyStates() {
  // Declare multiple state variables!
  const [age, setAge] = useState(42);
  const [fruit, setFruit] = useState('banana');
  const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
  // ...
}

这给我们的一个非常大的好处就是我们能够避免组件的 state 结构过于臃肿(因为之前每个 component class 只能有一个 state),能够独立处理每个 state。另一个好处就是这种写法非常直观,一眼就可以看出和这个 state 相关的两个变量,比如 [age, setAge]。

Effect hooks

import { 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>
  );
}

我们还需要解决一个问题,那就是怎样在 function component 里使用 life-cycles,生命周期函数。在这里,所有的 life-cycles,比如 componentDidMount, componentDidUpdate, shouldUpdate, 等等都集合成一个 Hook,叫做 useEffect。这个函数类似 redux 中的 subscribe,每当 React 因为 state 或是 props 而重新 render 的之后,就会触发 useEffect 里的这个 callback listener(在第一次 render 和每次 update 后触发)。

为什么叫 useEffect 呢?因为我们通常在生命周期内做的操作很多都会产生一些 side-effect(副作用)的操作,比如更新 DOM,fetch 数据,等等。

参考文档

ly2011 avatar Dec 02 '18 02:12 ly2011