React Hooks 详解:2026 年图解指南

发布: (2026年3月29日 GMT+8 06:35)
5 分钟阅读
原文: Dev.to

I’m sorry, but I can’t retrieve the article from the link you provided. If you paste the text you’d like translated here, I’ll be happy to translate it into Simplified Chinese while preserving the formatting.

useState

import { useState } from 'react';

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

  return (
     setCount(count + 1)}>
      Clicked {count} times
    
  );
}

何时使用: 组件在渲染之间需要记住的任何内容——表单值、切换状态、计数器。

注意: 状态更新是异步的。

// ❌ This won't work as expected
setCount(count + 1);
setCount(count + 1); // Both use the same `count` value

// ✅ Use the updater function instead
setCount(prev => prev + 1);
setCount(prev => prev + 1); // Now it's +2

Source:

useEffect

import { useEffect, useState } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    // 在 userId 变化的每次渲染后运行
    fetch(`/api/users/${userId}`)
      .then(r => r.json())
      .then(setUser);
  }, [userId]); // 依赖数组

  return {user?.name};
}

依赖数组

依赖项行为
[]挂载时运行一次
[value]value 变化时运行
每次渲染后都运行(通常是错误的)

清理

useEffect(() => {
  const subscription = subscribe(userId);

  return () => {
    subscription.unsubscribe(); // 清理!
  };
}, [userId]);

useContext

import { createContext, useContext, useState } from 'react';

// 1. Create the context
const ThemeContext = createContext('light');

// 2. Provide it at the top
function App() {
  const [theme, setTheme] = useState('dark');
  return (
    
      
    
  );
}

// 3. Use it anywhere in the tree
function Button() {
  const { theme } = useContext(ThemeContext);
  return Click me;
}

useRef

import { useRef } from 'react';

function TextInput() {
  const inputRef = useRef(null);

  const focusInput = () => {
    inputRef.current.focus();
  };

  return (
    <>
      
      聚焦
    
  );
}

也可用于存储不应触发重新渲染的值:

const renderCount = useRef(0);
renderCount.current += 1; // Doesn't cause re-render

useMemo

function ProductList({ products, minPrice }) {
  // Recalculates only when `products` or `minPrice` change
  const filtered = useMemo(() => {
    return products.filter(p => p.price >= minPrice);
  }, [products, minPrice]);

  return (
    
{filtered.map(p => - {p.name}
)}

  );
}

何时使用: 仅在您已测量到导致性能问题的真正昂贵的计算时使用。

useCallback

import { useCallback } from 'react';

function Parent({ id }) {
  // Without useCallback, a new function is created every render
  const handleClick = useCallback(() => {
    doSomethingWith(id);
  }, [id]);

  return ;
}

何时使用: 当将回调函数传递给 React.memo‑包装的子组件,以避免不必要的重新渲染。

useReducer

import { useReducer } from 'react';

const initialState = { count: 0, error: null, loading: false };

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

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

  return (
    
      Count: {state.count}
       dispatch({ type: 'increment' })}>+
       dispatch({ type: 'decrement' })}>-
    
  );
}

使用 useState 的替代方案: 当多个状态片段相互关联并一起变化时。

自定义 Hook(可组合性)

// 用于 API 调用的自定义 Hook
function useApi(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading(true);
    fetch(url)
      .then(r => {
        if (!r.ok) throw new Error(`HTTP ${r.status}`);
        return r.json();
      })
      .then(data => { setData(data); setLoading(false); })
      .catch(err => { setError(err.message); setLoading(false); });
  }, [url]);

  return { data, loading, error };
}

// 使用自定义 Hook
function UserList() {
  const { data, loading, error } = useApi('/api/users');

  if (loading) return ;
  if (error) return ;
  return 
{data.map(u => - {u.name}
)}
;
}

Hook Overview

HookPurpose
useState本地状态
useEffect副作用,数据获取
useContext在不使用 props 的情况下共享状态
useRefDOM 引用,可变值
useMemo对昂贵的计算进行记忆化
useCallback稳定的回调引用
useReducer复杂的状态逻辑
0 浏览
Back to Blog

相关文章

阅读更多 »