React Hooks完全指南:从基础到进阶

React Hooks完全指南:从基础到进阶

大家好,我是蔓蔓。React Hooks是React 16.8引入的一个革命性特性,它让我们能够在函数组件中使用状态和其他React特性。今天我来和大家分享React Hooks的完整用法。

基础Hooks

useState

javascript 复制代码
import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState('蔓蔓');

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <input 
        value={name} 
        onChange={(e) => setName(e.target.value)} 
      />
    </div>
  );
}

useEffect

javascript 复制代码
import { useState, useEffect } from 'react';

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

  useEffect(() => {
    const fetchUser = async () => {
      setLoading(true);
      const response = await fetch(`/api/users/${userId}`);
      const data = await response.json();
      setUser(data);
      setLoading(false);
    };

    fetchUser();

    // 清理函数
    return () => {
      console.log('Cleanup');
    };
  }, [userId]); // 依赖数组

  if (loading) return <div>Loading...</div>;
  
  return <div>{user.name}</div>;
}

useContext

javascript 复制代码
import { createContext, useContext } from 'react';

const ThemeContext = createContext('light');

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar() {
  const theme = useContext(ThemeContext);
  return <div>Theme: {theme}</div>;
}

进阶Hooks

useReducer

javascript 复制代码
import { 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 };
    case 'reset':
      return initialState;
    default:
      throw new Error();
  }
}

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

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
      <button onClick={() => dispatch({ type: 'reset' })}>Reset</button>
    </div>
  );
}

useCallback和useMemo

javascript 复制代码
import { useState, useCallback, useMemo } from 'react';

function expensiveCalculation(num) {
  console.log('Calculating...');
  return num * 2;
}

function App() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState('');

  // useMemo - 缓存计算结果
  const doubled = useMemo(() => expensiveCalculation(count), [count]);

  // useCallback - 缓存函数引用
  const handleClick = useCallback(() => {
    console.log('Clicked:', count);
  }, [count]);

  return (
    <div>
      <p>Count: {count}</p>
      <p>Doubled: {doubled}</p>
      <button onClick={() => setCount(c => c + 1)}>Increment</button>
      <input 
        value={name} 
        onChange={(e) => setName(e.target.value)} 
        placeholder="Name"
      />
      <button onClick={handleClick}>Log</button>
    </div>
  );
}

useRef

javascript 复制代码
import { useRef, useEffect } from 'react';

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

  useEffect(() => {
    inputRef.current.focus();
  }, []);

  return <input ref={inputRef} />;
}

// 存储可变值
function Timer() {
  const intervalRef = useRef(null);
  const [count, setCount] = useState(0);

  useEffect(() => {
    intervalRef.current = setInterval(() => {
      setCount(c => c + 1);
    }, 1000);

    return () => {
      clearInterval(intervalRef.current);
    };
  }, []);

  return <div>Count: {count}</div>;
}

自定义Hooks

javascript 复制代码
// useLocalStorage.js
import { useState, useEffect } from 'react';

export function useLocalStorage(key, initialValue) {
  const [storedValue, setStoredValue] = useState(() => {
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error(error);
      return initialValue;
    }
  });

  useEffect(() => {
    try {
      window.localStorage.setItem(key, JSON.stringify(storedValue));
    } catch (error) {
      console.error(error);
    }
  }, [key, storedValue]);

  return [storedValue, setStoredValue];
}

// 使用
function App() {
  const [name, setName] = useLocalStorage('name', '蔓蔓');
  
  return (
    <input 
      value={name} 
      onChange={(e) => setName(e.target.value)} 
    />
  );
}

Hooks规则

javascript 复制代码
// ✅ 正确:在函数顶层调用
function GoodComponent() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    console.log(count);
  });
  
  return <div>{count}</div>;
}

// ❌ 错误:在条件语句中调用
function BadComponent() {
  if (someCondition) {
    const [count, setCount] = useState(0); // ❌
  }
  
  return <div>Hello</div>;
}

// ✅ 正确:依赖数组包含所有依赖
function GoodEffect() {
  const [count, setCount] = useState(0);
  
  useEffect(() => {
    const timer = setInterval(() => {
      console.log(count);
    }, 1000);
    
    return () => clearInterval(timer);
  }, [count]);
  
  return <div>{count}</div>;
}

总结

React Hooks让函数组件更强大:

  1. useState管理状态
  2. useEffect处理副作用
  3. useContext跨组件传递数据
  4. useReducer管理复杂状态
  5. useCallback和useMemo优化性能
  6. 自定义Hooks复用逻辑

技术应当有温度,好的Hooks使用能让代码更简洁优雅。

相关推荐
做前端的娜娜子2 分钟前
第二个 AI 调用——invoke 阻塞式与 stream 流式生成
人工智能·llm·掘金·金石计划
sbjdhjd3 分钟前
大三网安秋招核心学习前言(AI 安全 + Web 漏洞 + 内网渗透全考点)
人工智能·网络协议·学习·安全·网络安全·开源·php
Narrastory5 分钟前
我用 Claude Code 写代码不到 2 小时,却花了 3 天做完这个软件—Vibe Coding 的正确姿势,是设计不是生成
前端·人工智能·github
chaoyuanl7 分钟前
悬空玻璃剧场源头厂家选型全解析|270°裸眼3D悬空玻璃剧场投资避坑指南
大数据·人工智能·3d·xr·娱乐·mr
tuanxiang7 分钟前
AI内容真人化处理:踩完3次审核红线后摸出来的落地流程
人工智能
阿里云大数据AI技术8 分钟前
穹彻智能 X 阿里云:自动化 UMI 数据处理产线,驱动先进具身大脑
人工智能
word12 分钟前
从零接入 MCP:把任意工具变成 AI 的能力(协议级实践)
人工智能·前端框架
冬哥聊AI15 分钟前
字节面试官:RAG不就是给大模型挂个知识库?别把这题答浅了
人工智能
9i编程17 分钟前
AI 只解决眼前那个坑【上篇】:来源、图片、鲁棒性,把能聊一处一处补齐
人工智能·openai·ai编程
晴天1618 分钟前
AgentLoop分享(上): 让 AI 真正“自主干活“-Day15
人工智能·python