技术文档中心
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
  • 入门基础

    • React 学习指南
    • React 快速入门
    • 状态管理基础
    • Hooks 基础
    • 组件通信
    • 生命周期与副作用
    • 实战项目
  • 进阶提升

    • Hooks 进阶
    • 组件设计模式
    • 性能优化
    • React Router
    • 表单处理
    • HTTP 请求
  • 状态管理

    • Context API
    • Redux 状态管理
    • Zustand 轻量状态管理
  • 高级主题

    • React + TypeScript
    • React 测试
    • 服务端渲染 (SSR)
    • 微前端架构

Hooks 基础

useState - 状态管理

基本用法

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  
  return (
    <div>
      <p>计数: {count}</p>
      <button onClick={() => setCount(count + 1)}>增加</button>
    </div>
  );
}

多个状态

function UserProfile() {
  const [name, setName] = useState('');
  const [age, setAge] = useState(0);
  const [email, setEmail] = useState('');

  return (
    <div>
      <input value={name} onChange={e => setName(e.target.value)} />
      <input type="number" value={age} onChange={e => setAge(e.target.value)} />
      <input value={email} onChange={e => setEmail(e.target.value)} />
    </div>
  );
}

对象状态

function Form() {
  const [user, setUser] = useState({
    name: '',
    age: 0,
    email: ''
  });

  const updateField = (field, value) => {
    setUser({
      ...user,
      [field]: value
    });
  };

  return (
    <div>
      <input 
        value={user.name} 
        onChange={e => updateField('name', e.target.value)} 
      />
      <input 
        type="number"
        value={user.age} 
        onChange={e => updateField('age', e.target.value)} 
      />
    </div>
  );
}

数组状态

function TodoList() {
  const [todos, setTodos] = useState([]);
  const [input, setInput] = useState('');

  const addTodo = () => {
    setTodos([...todos, { id: Date.now(), text: input }]);
    setInput('');
  };

  const removeTodo = (id) => {
    setTodos(todos.filter(todo => todo.id !== id));
  };

  return (
    <div>
      <input value={input} onChange={e => setInput(e.target.value)} />
      <button onClick={addTodo}>添加</button>
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>
            {todo.text}
            <button onClick={() => removeTodo(todo.id)}>删除</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

useEffect - 副作用

基本用法

import { useState, useEffect } from 'react';

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const timer = setInterval(() => {
      setSeconds(s => s + 1);
    }, 1000);

    // 清理函数
    return () => clearInterval(timer);
  }, []); // 空数组表示只在挂载时执行

  return <div>已运行 {seconds} 秒</div>;
}

依赖数组

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

  useEffect(() => {
    // userId 变化时重新获取
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => setUser(data));
  }, [userId]); // 依赖 userId

  if (!user) return <div>加载中...</div>;
  return <div>{user.name}</div>;
}

多个 useEffect

function Dashboard() {
  const [user, setUser] = useState(null);
  const [posts, setPosts] = useState([]);

  // 获取用户信息
  useEffect(() => {
    fetch('/api/user')
      .then(res => res.json())
      .then(data => setUser(data));
  }, []);

  // 获取文章列表
  useEffect(() => {
    fetch('/api/posts')
      .then(res => res.json())
      .then(data => setPosts(data));
  }, []);

  return <div>...</div>;
}

常见场景

// 1. 监听窗口大小
function WindowSize() {
  const [size, setSize] = useState({
    width: window.innerWidth,
    height: window.innerHeight
  });

  useEffect(() => {
    const handleResize = () => {
      setSize({
        width: window.innerWidth,
        height: window.innerHeight
      });
    };

    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return <div>{size.width} x {size.height}</div>;
}

// 2. 文档标题
function PageTitle({ title }) {
  useEffect(() => {
    document.title = title;
  }, [title]);

  return <div>...</div>;
}

// 3. 本地存储
function Settings() {
  const [theme, setTheme] = useState(() => {
    return localStorage.getItem('theme') || 'light';
  });

  useEffect(() => {
    localStorage.setItem('theme', theme);
  }, [theme]);

  return (
    <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
      切换主题
    </button>
  );
}

useRef - 引用

DOM 引用

import { useRef, useEffect } from 'react';

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

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

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

保存值

function ClickCounter() {
  const [renderCount, setRenderCount] = useState(0);
  const clickCountRef = useRef(0);

  const handleClick = () => {
    clickCountRef.current++;
    console.log('点击次数:', clickCountRef.current);
  };

  return (
    <div>
      <button onClick={handleClick}>点击</button>
      <button onClick={() => setRenderCount(renderCount + 1)}>
        重新渲染 ({renderCount})
      </button>
    </div>
  );
}

保存前一个值

function usePrevious(value) {
  const ref = useRef();
  
  useEffect(() => {
    ref.current = value;
  }, [value]);
  
  return ref.current;
}

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

  return (
    <div>
      <p>当前: {count}</p>
      <p>之前: {prevCount}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

useContext - 上下文

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

// 创建 Context
const ThemeContext = createContext();

// Provider 组件
function App() {
  const [theme, setTheme] = useState('light');

  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

// 使用 Context
function Toolbar() {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const { theme, setTheme } = useContext(ThemeContext);

  return (
    <button 
      style={{ 
        background: theme === 'light' ? '#fff' : '#333',
        color: theme === 'light' ? '#000' : '#fff'
      }}
      onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}
    >
      当前主题: {theme}
    </button>
  );
}
最近更新: 2026/1/27 15:51
Contributors: hailong
Prev
状态管理基础
Next
组件通信