FumadocsZDecode
React

useState Hook 状态管理

useState 是 React 最基础的 Hook,用于在函数组件中添加状态。它允许你在组件重新渲染时保留状态值。


一、基本语法

使用数组解构获取状态值和更新函数。

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

语法说明

  • count:当前状态值
  • setCount:更新状态的函数
  • 0:初始状态值

二、常见使用场景

表单输入

function InputField() {
  const [text, setText] = React.useState('')
  
  return (
    <div>
      <input
        value={text}
        onChange={(e) => setText(e.target.value)}
        placeholder="请输入"
      />
      <p>你输入的是:{text}</p>
    </div>
  )
}

多个状态

function UserForm() {
  const [name, setName] = React.useState('')
  const [age, setAge] = React.useState(0)
  
  return (
    <div>
      <input value={name} onChange={(e) => setName(e.target.value)} placeholder="姓名" />
      <input
        type="number"
        value={age}
        onChange={(e) => setAge(Number(e.target.value))}
        placeholder="年龄"
      />
    </div>
  )
}

对象状态

function Profile() {
  const [user, setUser] = React.useState({ name: '', email: '' })
  
  return (
    <div>
      <input
        value={user.name}
        onChange={(e) => setUser({ ...user, name: e.target.value })}
        placeholder="姓名"
      />
      <input
        value={user.email}
        onChange={(e) => setUser({ ...user, email: e.target.value })}
        placeholder="邮箱"
      />
    </div>
  )
}

三、进阶用法:函数式更新

当新状态依赖于前一个状态时,传入一个函数而不是直接的值。这确保在多次更新时不会丢失中间状态。

function Counter() {
  const [count, setCount] = React.useState(0)
  
  // 连续调用 setCount 时,每次都基于最新的 count 值
  function doubleIncrement() {
    setCount((prev) => prev + 1)
    setCount((prev) => prev + 1)
  }
  
  return (
    <div>
      <p>{count}</p>
      <button onClick={doubleIncrement}>增加 2</button>
    </div>
  )
}

惰性初始化

如果初始状态需要复杂计算,传入一个初始化函数。该函数只在组件首次挂载时执行。

function ExpensiveComponent() {
  const [state, setState] = React.useState(() => {
    // 这个计算只执行一次,在组件挂载时
    return someExpensiveComputation()
  })
  
  return <div>{state}</div>
}

四、注意事项

状态更新是异步的

调用 setState 后,状态不会立即改变,而是在下一次渲染时才会更新。

function AsyncExample() {
  const [count, setCount] = React.useState(0)
  
  function handleClick() {
    setCount(count + 1)
    console.log(count) // 输出的是更新前的值
  }
  
  return <button onClick={handleClick}>点击</button>
}

状态必须是不可变的

不要直接修改对象或数组,而是创建新的副本。

// ✗ 错误:直接修改
const [user, setUser] = React.useState({ name: 'John' })
user.name = 'Jane'
setUser(user) // 可能不会触发重新渲染

// ✓ 正确:创建新对象
setUser({ ...user, name: 'Jane' })

// ✗ 错误:直接修改数组
const [items, setItems] = React.useState(['a', 'b'])
items.push('c')
setItems(items)

// ✓ 正确:创建新数组
setItems([...items, 'c'])

Rules of Hooks

  • 只在组件顶层调用 useState,不要在循环、条件或嵌套函数中调用
  • 只在 React 函数组件或自定义 Hook 中使用

核心要点useState 通过数组解构返回状态值和更新函数。状态更新是异步的,必须遵守不可变性原则——修改复杂状态时总是创建新对象,不要直接修改原有值。

On this page