内置 React 钩子

Hooks 让你可以在组件中使用不同的 React 功能。你可以使用内置的 Hooks,也可以将它们组合起来构建你自己的 Hooks。本页面列出了 React 中所有内置的 Hooks。


状态钩子

🌐 State Hooks

State 让一个组件能够“记住”信息,比如用户输入。 例如,一个表单组件可以使用 state 来存储输入值,而一个图片图库组件可以使用 state 来存储所选图片的索引。

要向组件添加状态,请使用以下钩子之一:

🌐 To add state to a component, use one of these Hooks:

function ImageGallery() {
const [index, setIndex] = useState(0);
// ...

上下文钩子

🌐 Context Hooks

上下文 允许一个组件从远程父组件接收信息而不通过 props 传递。 例如,你应用的顶层组件可以将当前的 UI 主题传递给下方的所有组件,无论它们嵌套多深。

function Button() {
const theme = useContext(ThemeContext);
// ...

引用钩子

🌐 Ref Hooks

Refs 让一个组件保存一些不用于渲染的信息, 比如 DOM 节点或定时器 ID。与 state 不同,更新 ref 不会重新渲染你的组件。Refs 是一种从 React 范式中“逃脱”的方法。当你需要与非 React 系统(如内置浏览器 API)交互时,它们非常有用。

  • useRef 声明了一个 ref。你可以在其中存储任何值,但它最常用于存储 DOM 节点。
  • useImperativeHandle 让你自定义组件暴露的 ref。这很少使用。
function Form() {
const inputRef = useRef(null);
// ...

副作用钩子

🌐 Effect Hooks

Effects 让组件连接并与外部系统同步。这包括处理网络、浏览器 DOM、动画、使用不同 UI 库编写的小部件以及其他非 React 代码。

  • useEffect 将一个组件连接到外部系统。
function ChatRoom({ roomId }) {
useEffect(() => {
const connection = createConnection(roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId]);
// ...

Effects 是 React 范式中的“应急方案”。不要使用 Effects 来协调应用的数据流。如果你没有与外部系统交互,你可能不需要 Effect。

🌐 Effects are an “escape hatch” from the React paradigm. Don’t use Effects to orchestrate the data flow of your application. If you’re not interacting with an external system, you might not need an Effect.

useEffect 有两种很少使用的变体,它们在时序上有所不同:

🌐 There are two rarely used variations of useEffect with differences in timing:

  • useLayoutEffect 在浏览器重绘屏幕之前触发。你可以在这里测量布局。
  • useInsertionEffect 会在 React 对 DOM 进行更改之前触发。库可以在这里插入动态 CSS。

你也可以将事件与效果分开:

🌐 You can also separate events from Effects:

  • useEffectEvent 创建一个非响应性的事件,可从任何 Effect 钩子触发。---

性能钩子

🌐 Performance Hooks

优化重新渲染性能的一种常见方法是跳过不必要的工作。例如,如果数据自上一次渲染以来没有变化,你可以告诉 React 重用缓存的计算结果或跳过重新渲染。

🌐 A common way to optimize re-rendering performance is to skip unnecessary work. For example, you can tell React to reuse a cached calculation or to skip a re-render if the data has not changed since the previous render.

要跳过计算和不必要的重新渲染,请使用以下钩子之一:

🌐 To skip calculations and unnecessary re-rendering, use one of these Hooks:

  • useMemo 允许你缓存一次昂贵计算的结果。
  • useCallback 允许你在将函数传递给优化组件之前缓存该函数的定义。
function TodoList({ todos, tab, theme }) {
const visibleTodos = useMemo(() => filterTodos(todos, tab), [todos, tab]);
// ...
}

有时,你无法跳过重新渲染,因为屏幕实际上需要更新。在这种情况下,你可以通过将必须同步的阻塞更新(比如在输入框中输入)与不需要阻塞用户界面的非阻塞更新(比如更新图表)分开来提高性能。

🌐 Sometimes, you can’t skip re-rendering because the screen actually needs to update. In that case, you can improve performance by separating blocking updates that must be synchronous (like typing into an input) from non-blocking updates which don’t need to block the user interface (like updating a chart).

要确定渲染的优先级,请使用以下钩子之一:

🌐 To prioritize rendering, use one of these Hooks:

  • useTransition 允许你将状态转换标记为非阻塞,并允许其他更新中断它。
  • useDeferredValue 允许你延迟更新 UI 中非关键的部分,并让其他部分先更新。

其他钩子

🌐 Other Hooks

这些钩子主要对库作者有用,并且在应用代码中不常用。

🌐 These Hooks are mostly useful to library authors and aren’t commonly used in the application code.

  • useDebugValue 让你自定义 React DevTools 为你的自定义 Hook 显示的标签。
  • useId 允许组件将唯一 ID 与自身关联。通常与无障碍 API 一起使用。
  • useSyncExternalStore 允许一个组件订阅外部存储。

你自己的钩子

🌐 Your own Hooks

你也可以将 自定义 Hooks 定义为 JavaScript 函数。

🌐 You can also define your own custom Hooks as JavaScript functions.