终极 React Hooks 指南

发布: (2025年12月21日 GMT+8 02:30)
7 min read
原文: Dev.to

I’m happy to translate the article for you, but I’ll need the full text you’d like translated. Could you please paste the content (or the portion you want translated) here? I’ll keep the source link exactly as you provided and preserve all formatting, markdown, and code blocks.

介绍

React Hooks 是函数,允许你在函数组件中“挂钩”React 的状态和生命周期特性。它们在 React 16.8 中引入。下面列出了一些常用的 React hooks、它们的解释以及使用示例。此外,本指南还涵盖了如何创建自定义 hooks。

1. useState

The useState hook lets you add state to function components.

说明

useState returns an array with two elements: the current state value and a function to update it.

用法

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    
      
You clicked {count} times

       setCount(count + 1)}>
        Click me
      
    
  );
}

2. useEffect

useEffect Hook 让你在函数组件中执行副作用。

带依赖项的 useEffect

useEffect 在首次渲染后以及每次更新后运行。你也可以指定依赖项来控制 effect 的执行时机。

用法

import React, { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]);

  return (
    
      
You clicked {count} times

       setCount(count + 1)}>
        Click me
      
    
  );
}

空依赖数组 []useEffect

仅在初始渲染后运行一次(类似于 componentDidMount)。

useEffect(() => {
  console.log('This runs only once after the first render');
}, []);

使用场景: 组件挂载时获取数据、设置事件监听器等。

没有依赖项的 useEffect

在每次渲染时(包括首次渲染和后续重新渲染)都会运行。

useEffect(() => {
  console.log('This runs after every render');
});

使用场景: 执行不依赖特定状态变化的代码,如日志记录或动画。

useEffect 中的清理函数

如果 useEffect 返回一个函数,它会在下一个 effect 运行之前或组件卸载时执行清理。

useEffect(() => {
  const interval = setInterval(() => {
    console.log('Interval running...');
  }, 1000);

  return () => {
    clearInterval(interval); // Cleanup on unmount
  };
}, []);

使用场景: 清除事件监听器、取消 API 调用、清除定时器等。

3. useContext

useContext 钩子让你能够访问上下文的值。

说明

useContext 接受一个上下文对象(由 React.createContext 返回的值),并返回当前的上下文值。

用法

import React, { useContext } from 'react';

const MyContext = React.createContext();

function MyComponent() {
  const value = useContext(MyContext);
  return {value};
}

function App() {
  return (
    
      
    
  );
}

4. useReducer

useReducer hook 是 useState 的替代方案,用于管理复杂的状态逻辑。

说明

useReducer 返回一个数组,包含当前状态和用于触发状态更新的 dispatch 函数。

用法

import React, { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error('Unknown action');
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    
      
Count: {state.count}

       dispatch({ type: 'increment' })}>
        Increment
      
       dispatch({ type: 'decrement' })}>
        Decrement
      
    
  );
}

5. useCallback

useCallback 钩子返回一个已记忆的回调函数。

说明

useCallback 返回回调函数的记忆版本,只有在依赖项之一发生变化时才会更新。

用法

import React, { useState, useCallback } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  const increment = useCallback(() => {
    setCount(prevCount => prevCount + 1);
  }, [count]);

  return (
    
      
You clicked {count} times

      Click me
    
  );
}

6. useMemo

useMemo Hook 返回一个已记忆的值。

说明

只有当其依赖项之一发生变化时,useMemo 才会重新计算记忆的值。

用法

import React, { useState, useMemo } from 'react';

function ExpensiveComponent({ value }) {
  // 模拟一次耗时的计算
  const computed = useMemo(() => {
    let result = 0;
    for (let i = 0; i Result: {computed};
}

欢迎根据项目需求,添加 useRefuseLayoutEffect 或自定义 Hook 等内容,以扩展本指南。

6. useMemo(附加示例)

function ExpensiveCalculationComponent() {
  const [count, setCount] = useState(0);
  const [value, setValue] = useState("");

  const expensiveCalculation = useMemo(() => {
    // Assume this is an expensive calculation
    return count * 2;
  }, [count]);

  return (
    
      
Expensive Calculation: {expensiveCalculation}

       setCount(count + 1)}>Increment
       setValue(e.target.value)} />
    
  );
}

7. useRef

useRef 钩子返回一个可变的 ref 对象。

说明

useRef 对于访问 DOM 元素或在渲染之间持久化值非常有用。

用法

import React, { useRef } from "react";

function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    inputEl.current.focus();
  };

  return (
    
      
      Focus the input
    
  );
}

8. useImperativeHandle

useImperativeHandle 钩子用于自定义在使用 ref 时暴露的实例值。

说明

useImperativeHandle 应与 React.forwardRef 一起使用。

用法

import React, { useRef, useImperativeHandle, forwardRef } from "react";

const FancyInput = forwardRef((props, ref) => {
  const inputRef = useRef();

  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    },
  }));

  return ;
});

function Parent() {
  const inputRef = useRef();

  return (
    
      
       inputRef.current.focus()}>聚焦输入
    
  );
}

9. useLayoutEffect

useLayoutEffect 钩子在所有 DOM 变更之后运行。

说明

useLayoutEffectuseEffect 类似,但它会在所有 DOM 变更后同步触发。

用法

import React, { useLayoutEffect, useRef } from "react";

function LayoutEffectComponent() {
  const divRef = useRef();

  useLayoutEffect(() => {
    console.log(divRef.current.getBoundingClientRect());
  });

  return Hello, world!;
}

10. useDebugValue

useDebugValue 钩子用于在 React DevTools 中为自定义 Hook 显示标签。

说明

useDebugValue 对调试自定义 Hook 很有帮助。

用法

import React, { useState, useDebugValue } from "react";

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useState(null);

  useDebugValue(isOnline ? "Online" : "Offline");

  // Imagine this is an actual implementation
  return isOnline;
}

11. 自定义 Hook

自定义 Hook 允许你将组件逻辑提取到可复用的函数中。

说明

自定义 Hook 是普通的 JavaScript 函数,能够调用其他 Hook。

示例:useFetch

import { useState, useEffect } from "react";

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetch(url)
      .then((response) => response.json())
      .then((data) => {
        setData(data);
        setLoading(false);
      });
  }, [url]);

  return { data, loading };
}

export default useFetch;

自定义 Hook 的使用

import React from "react";
import useFetch from "./useFetch";

function App() {
  const { data, loading } = useFetch("https://api.example.com/data");

  if (loading) {
    return Loading...;
  }

  return (
    
      {JSON.stringify(data, null, 2)}
    
  );
}

export default App;

本指南提供了 React Hook 的全面概述,包括它们的用法以及如何创建自定义 Hook。

Back to Blog

相关文章

阅读更多 »