SuperAPI AI 工具集

react-hooks

前端与建站

查看项目

更新于 10-16 07:52

技能介绍

用途

当用户需要以下操作时,可使用本技能:

  • 使用 React 内置 Hook(useState、useEffect、useContext、useRef、useMemo、useCallback)
  • 创建自定义 Hook 以复用有状态逻辑
  • 使用 useReducer 管理复杂状态
  • 通过记忆化 Hook 优化组件性能
  • 使用 useEffect 处理副作用(数据获取、订阅、定时器)
  • 理解并遵循 Hooks 规则

主要能力

本技能提供 React Hooks 的代码生成与指导,覆盖内置 Hook、自定义 Hook 模式、复杂状态管理、性能优化与副作用处理,并强调依赖数组、清理函数与 Hooks 规则的正确使用。

使用方式

工作流程:

  1. 识别哪种 Hook 最符合用户需求
  2. 应用 Hooks 规则:只在顶层调用 Hook;只从 React 函数中调用 Hook
  3. 生成带有正确依赖数组和清理函数的 Hook 代码
  4. 验证是否存在过期闭包或缺失依赖

1. useState 与 useEffect

import { useState, useEffect } from 'react';

function useUserData(userId: string) {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    let cancelled = false;
    setLoading(true);

    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => {
        if (!cancelled) {
          setUser(data);
          setLoading(false);
        }
      })
      .catch(err => {
        if (!cancelled) {
          setError(err);
          setLoading(false);
        }
      });

    return () => { cancelled = true; }; // Cleanup on unmount or userId change
  }, [userId]);

  return { user, loading, error };
}

2. 使用 useReducer 处理复杂状态

import { useReducer } from 'react';

type State = { count: number; step: number };
type Action = { type: 'increment' } | { type: 'decrement' } | { type: 'setStep'; payload: number };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case 'increment': return { ...state, count: state.count + state.step };
    case 'decrement': return { ...state, count: state.count - state.step };
    case 'setStep':   return { ...state, step: action.payload };
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0, step: 1 });
  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </div>
  );
}

3. useMemo 与 useCallback

import { useMemo, useCallback } from 'react';

function FilteredList({ items, filter }: { items: Item[]; filter: string }) {
  // Memoize expensive computation
  const filtered = useMemo(
    () => items.filter(item => item.name.includes(filter)),
    [items, filter]
  );

  // Memoize callback to prevent child re-renders
  const handleSelect = useCallback((id: string) => {
    console.log('Selected:', id);
  }, []);

  return <ItemList items={filtered} onSelect={handleSelect} />;
}

4. 自定义 Hook 模式

import { useState, useCallback } from 'react';

function useToggle(initialValue = false): [boolean, () => void] {
  const [value, setValue] = useState(initialValue);
  const toggle = useCallback(() => setValue(prev => !prev), []);
  return [value, toggle];
}

// Usage
function Modal() {
  const [isOpen, toggleOpen] = useToggle(false);
  return <>{isOpen && <div>Modal Content</div>}<button onClick={toggleOpen}>Toggle</button></>;
}

适用场景

  • 使用内置 Hook 构建组件状态与副作用逻辑
  • 抽取可复用的有状态逻辑为自定义 Hook
  • 以 useReducer 管理复杂状态转换
  • 通过 useMemo、useCallback 优化渲染性能
  • 处理数据获取、订阅、定时器等副作用

最佳实践

  • 始终在 useEffect 依赖数组中包含所有依赖(使用 ESLint 插件 react-hooks/exhaustive-deps)
  • 在 useEffect 返回函数中清理订阅、定时器和监听器
  • 自定义 Hook 以 use 前缀命名(如 useAuth、useFetch)
  • 绝不在条件、循环或嵌套函数中调用 Hook
  • 仅在存在可衡量的性能收益时使用 useCallback 和 useMemo
  • 当状态转换复杂时,优先使用 useReducer 而非多个 useState

限制

本技能的具体收费、价格、平台支持等信息暂未提供。

资源

  • Hooks 参考:https://react.dev/reference/react
  • Hooks 规则:https://react.dev/reference/rules/rules-of-hooks

关键词

React Hooks、useState、useEffect、useContext、useReducer、useMemo、useCallback、useRef、自定义 Hook、Hooks 规则、依赖数组、清理、记忆化