React Hooks 总结
什么是 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 数据,等等。