钩子让你可以使用组件中的不同 React 功能。你可以使用内置的钩子或组合它们来构建你自己的钩子。本页列出了 React 中所有内置的钩子。
¥Hooks let you use different React features from your components. You can either use the built-in Hooks or combine them to build your own. This page lists all built-in Hooks in React.
状态钩子
¥State Hooks
状态让组件 “记住” 信息,如用户输入。例如,表单组件可以使用状态来存储输入值,而图片库组件可以使用状态来存储所选图片索引。
¥State lets a component “remember” information like user input. For example, a form component can use state to store the input value, while an image gallery component can use state to store the selected image index.
要向组件添加状态,请使用以下钩子之一:
¥To add state to a component, use one of these Hooks:
-
useState
声明了一个你可以直接更新的状态变量。¥
useState
declares a state variable that you can update directly. -
useReducer
在 reducer 函数 中声明了一个带有更新逻辑的状态变量。¥
useReducer
declares a state variable with the update logic inside a reducer function.
function ImageGallery() {
const [index, setIndex] = useState(0);
// ...
上下文钩子
¥Context Hooks
上下文让一个组件 从远处的父级那里接收信息而不将其作为属性传递。例如,你的应用的顶层组件可以将当前的 UI 主题传递给下面的所有组件,无论有多深。
¥Context lets a component receive information from distant parents without passing it as props. For example, your app’s top-level component can pass the current UI theme to all components below, no matter how deep.
-
useContext
读取并订阅上下文。¥
useContext
reads and subscribes to a context.
function Button() {
const theme = useContext(ThemeContext);
// ...
引用钩子
¥Ref Hooks
引用让组件 保存一些不用于渲染的信息, 像 DOM 节点或超时 ID。与状态不同,更新引用不会重新渲染你的组件。引用是来自 React 范式的 “应急方案”。当你需要使用非 React 系统(例如内置浏览器 API)时,它们很有用。
¥Refs let a component hold some information that isn’t used for rendering, like a DOM node or a timeout ID. Unlike with state, updating a ref does not re-render your component. Refs are an “escape hatch” from the React paradigm. They are useful when you need to work with non-React systems, such as the built-in browser APIs.
-
useRef
声明了一个引用。你可以在其中保存任何值,但通常它用于保存 DOM 节点。¥
useRef
declares a ref. You can hold any value in it, but most often it’s used to hold a DOM node. -
useImperativeHandle
允许你自定义组件公开的引用。这很少使用。¥
useImperativeHandle
lets you customize the ref exposed by your component. This is rarely used.
function Form() {
const inputRef = useRef(null);
// ...
副作用钩子
¥Effect Hooks
副作用让组件 连接到外部系统并与之同步。这包括处理网络、浏览器 DOM、动画、使用不同的 UI 库编写的小部件,以及其他非 React 代码。
¥Effects let a component connect to and synchronize with external systems. This includes dealing with network, browser DOM, animations, widgets written using a different UI library, and other non-React code.
function ChatRoom({ roomId }) {
useEffect(() => {
const connection = createConnection(roomId);
connection.connect();
return () => connection.disconnect();
}, [roomId]);
// ...
副作用是来自 React 范式的 “应急方案”。不要使用副作用来编排应用的数据流。如果你不与外部系统交互,你可能不需要副作用。
¥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
在浏览器重新绘制屏幕之前触发。你可以在此处测量布局。¥
useLayoutEffect
fires before the browser repaints the screen. You can measure layout here. -
useInsertionEffect
在 React 更改 DOM 之前触发。库可以在此处插入动态 CSS。¥
useInsertionEffect
fires before React makes changes to the DOM. Libraries can insert dynamic CSS here.
性能钩子
¥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
允许你缓存昂贵计算的结果。¥
useMemo
lets you cache the result of an expensive calculation. -
useCallback
允许你在将函数定义传递给优化组件之前缓存它。¥
useCallback
lets you cache a function definition before passing it down to an optimized component.
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
允许你将状态转场标记为非阻塞,并允许其他更新中断它。¥
useTransition
lets you mark a state transition as non-blocking and allow other updates to interrupt it. -
useDeferredValue
允许你推迟更新 UI 的非关键部分,让其他部分先更新。¥
useDeferredValue
lets you defer updating a non-critical part of the UI and let other parts update first.
其他钩子
¥Other Hooks
这些钩子主要对库作者有用,并且在应用代码中不常用。
¥These Hooks are mostly useful to library authors and aren’t commonly used in the application code.
-
useDebugValue
允许你自定义 React DevTools 为你的自定义钩子显示的标签。¥
useDebugValue
lets you customize the label React DevTools displays for your custom Hook. -
useId
允许组件将唯一 ID 与自身相关联。通常与可访问性 API 一起使用。¥
useId
lets a component associate a unique ID with itself. Typically used with accessibility APIs. -
useSyncExternalStore
允许组件订阅外部存储。¥
useSyncExternalStore
lets a component subscribe to an external store.
-
useActionState
允许你管理操作的状态。¥
useActionState
allows you to manage state of actions.
你自己的钩子
¥Your own Hooks
你还可以将 定义你自己的自定义钩子 作为 JavaScript 函数。
¥You can also define your own custom Hooks as JavaScript functions.