React Hooks 终极速查表
React Hooks 是 React 世界中的新宠。我正在稳步地编写越来越多的 Hooks 代码,我认为制作一份速查表来回顾它很有用,它涵盖了基本的 Hooks 以及其复杂之处useEffect
。查看官方的Hooks API 参考,了解更多详细信息。
目录
useEffect(用于生命周期方法)
useEffect
除其他外,它允许您编写自己的副作用并在需要时触发重新渲染。
但为了更简单起见,useEffect 也替代了生命周期方法。我们来谈谈它们。
替代 componentDidUpdate + componentDidMount
什么时候运行?每次渲染时
有什么问题?它不仅仅是componentDidUpdate
替代品,还能在挂载上运行。所以它不是一对一的。
重要功能? useEffect 可以接受第二个参数,但您必须跳过该参数。您还可以返回一个函数,我们将在下一节中介绍。
代码沙盒游乐场: 去玩吧
句法:
import { useEffect } from 'react';
useEffect(() => {
// whatever runs here will run on each re-render
});
替代 componentDidMount + componentWillUnmount
什么时候运行?在组件挂载和卸载时
有什么问题?语法和上一个用例非常相似。它让我困惑了好几次,但只要你读了文档就明白了。如果这个效果运行多次,请确保传入第二个参数。
重要特性?这是一个只运行一次的效果。挂载逻辑位于效果函数体中,卸载/清理逻辑位于效果返回的函数中。
代码沙盒游乐场: 去玩吧
句法:
import { useEffect } from 'react';
useEffect(() => {
// run mount logic here such as fetching some data
return () => {
// unmount logic goes here
};
}, []); // note the empty array
你可以将mount
或unmount
逻辑留空,这样就只使用其中一个生命周期替代项。这意味着:
- 将
mount
逻辑留空,以便只unmount
运行逻辑(替代 justcomponentWillUnmount
) - 不返回任何内容,只
mount
运行逻辑(替代 justcomponentDidMount
)
useEffect 用于副作用
useEffect
的主要目标是涵盖所有你可能想要使用的副作用。副作用本质上是你在组件内部执行的操作,这些操作会影响整个世界。无论是网络请求、设置文档标题,还是其他什么。
必要时运行
何时运行?组件重新渲染时,useEffect
会检查依赖项。如果依赖项值发生变化,useEffect 将运行该 effect。
有什么问题吗? React 会进行浅比较。如果你使用一个修改过的对象或数组,React 会认为没有任何变化。
重要特性useEffect 会在内容不变时跳过运行 effect。您实际上不必在 effect 中使用依赖项值。您可以将 prop 值作为依赖项传入。
代码沙盒游乐场: 去玩吧
句法:
import { useEffect } from 'react';
function SomeComponent(props) {
useEffect(() => {
// logic runs only when dependency variables changed
}, [arrOfDependency, values, props.id]); // array of values to check if they've changed
}
潜在用例
由于钩子比较难解释,我想提供一个用例列表
- 当 prop 发生变化以获取新数据时,运行副作用(如获取)
- 仅当计算值发生变化时才运行资源密集型计算
- 当值更新时更新页面(如文档标题)
useState
状态可能是人们从无状态(功能)组件转换为类组件的原因。允许useState
我们拥有没有类的状态组件。
它返回什么?当前状态和一个允许你设置状态的函数。
有什么问题吗?状态设置函数会用新状态替换旧状态,而不是像类状态那样合并它们。你需要在设置状态之前自行合并对象。
重要特性:useState
您可以在组件中使用任意数量的钩子。向 传递任何值useState
都会创建初始状态。此外,约定俗成地不要使用变量state
和 ,setState
而是使用上下文名称(例如user
和setUser
)。useState
状态 可以接受任何值,不必是对象。
Code Sandbox 游乐场: 查看 useState 示例
句法:
import { useState } from 'react';
// setup
const defaultValue = { name: "Antonin" };
const [state, setState] = useState(defaultValue);
// scenario 1 usage
// resulting state only contains key `user` with value 'antjanus'
setState({ user: 'antjanus' });
// scenario 2 usage
// resulting state contains key `name` with value 'A. Januska'
setState({ name: 'A. Januska' });
// scenario 3 usage
// resulting state is a merger between `{ name: 'A. Januska' }` and `{ user: 'antjanus'}`
setState({ ...state, user: 'antjanus'});
useReducer
useReducer
是一种替代方案useState
,如果您以前使用过 Redux,那么它看起来会很熟悉。
参数是什么?它返回什么? useReducer
接受一个reducer
函数和initialState
。它返回当前值state
和一个dispatcher
(听起来很熟悉?)
它是如何运行的?当状态改变时,dispatch
会返回一个具有类型和数据负载的对象(更多信息请阅读Flux 标准操作)。reducer
我们传入 useReducer 的参数将接收当前状态和已调度的对象。它返回新的状态。
有什么问题?这是一个更复杂的工作流程,但如果你使用过 Redux,它的工作方式就和你预期的一样。
重要特性: Reducer 每次调度时都会运行。它可以访问之前的状态。useReducer
此外,它还包含一个可用于创建初始状态的第三个参数。
Code Sandbox 游乐场: 查看 useReducer 示例
句法
import { useReducer } from 'react';
function reducer(currentState, action) {
switch(action.type) {
// handle each action type and how it affects the current state here
}
}
function SomeComponent() {
const [state, dispatch] = useReducer(reducer, initialState);
dispatch({ type: 'ADD', payload: data }); // { type: 'ADD', payload: data } gets passed into the `reducer` as the `action` argument while `state` gets passed in as the `currentState` argument
}
构建你自己的 Hooks
关于构建自定义钩子的简要说明。它非常简单,只需使用现有的钩子,并将它们组合在一个以 开头的函数中即可use
。以下是一个钩子的简单示例useUser
。
有什么要求?函数必须以关键字 开头use
。例如useUser
或useSomethingElse
。
重要特性:您可以在自定义钩子中调用任何钩子,并且它可以按预期工作。
Code Sandbox 游乐场: 查看自定义钩子示例
句法:
import { useEffect } from 'react';
function useUser(userId) {
let [user, setUser] = useState(null);
useEffect(() => {
fetch(`/api/user/${userId}`)
.then(data => data.toJSON())
.then(data => setUser(data));
}, [userId]);
return user;
}
function SomeComponent(props) {
const user = useUser(props.id);
}
其余的呢?
您还可以使用其他钩子,例如useMemo
、useCallback
等等。我想说的是,这些都是更高级的钩子,如果您了解基本的钩子,请继续阅读官方文档。
我还了解其中许多都有一些高级用法示例(例如将 useReducer 传递dispatch
到多个级别)。
如果您发现任何错误或未包含的额外有用信息,请告诉我!我会将其添加到文章中!
文章来源:https://dev.to/antjanus/the-definitive-react-hooks-cheatsheet-2ebn你觉得这份速查表有用吗?请我喝杯咖啡,这样我就可以继续写下去,创作更多内容了!:) 你也可以在 Twitter 上关注我