React hooks - useState

useState

在hooks出现之前,react的函数式组件也叫做无状态组件(函数里面无法创建属于自己的状态,只能使用props接收)

用法

一个管理状态的 hooks,能让函数组件拥有自己的状态,实现状态的初始化、读取、更新。

特点

  1. 状态变化时,会触发函数组件的重新执行,并根据最新的数据更新渲染 DOM 结构
  2. 以函数的形式为状态赋初始值
  3. 异步变更状态,useState() 返回一个以异步形式变更状态的函数,修改状态后无法立即拿到最新的状态
  4. 结合useEffect监听状态的变化
javascript 复制代码
import React, { useState } from 'react'

export const Count: React.FC = () => {
  const [count, setCount] = useState(0) // 默认初始值undefined,useState只有首次渲染会执行
  // 以函数的形式为状态赋初始值,useState也只会首次渲染执行,更新渲染不执行
  const [date] = useState(() => {
    const dt = new Date()
    return { year: dt.getFullYear(), mouth: dt.getMonth() + 1, day: dt.getDate()}
  })
  useEffect(()=>{
    console.log(count) // 可以监听到最新的值
  },count)
  console.log('组件被重新渲染了') // 每次 count 值发生变化,都会打印
  return (
    <>
      <h1>{count}</h1> <button onClick={() => {
          setCount(count + 1)
          console.log(count) // 打印的还是上一次的值
      }}>+1</button>
      <h2>{date.year}年{date.mouth}月{date.day}日{date.second}秒</h2>
    </>
  )
}

注意事项

  1. 组件rerender时useState不会被重复初始化
  2. 要更新对象类型的值
    须使用展开运算符或 Object.assign()生成新对象覆盖旧对象,才能触发组件的重新渲染
javascript 复制代码
import React, { useState } from 'react'

export const UserInfo: React.FC = () => {
  const [user, setUser] = useState({name: 'zs',age: 12})
  const updateUserInfo = () => {
    // user.name = 'Jesse Pinkman' // 错误使用:因为set 函数内部,会对更新前后的值进行对比,不会触发组件的重新渲染
    // 解决方案:用新对象的引用替换旧对象的引用,即可正常触发组件的重新渲染
    // setUser({ ...user })
    // setUser(Object.assign({}, user))
    setUser({ ...user, name: 'Jesse Pinkman' })
  }

  return (
    <>
      <h1>用户信息:</h1>
      <p>姓名:{user.name}</p>
      <p>年龄:{user.age}</p>
      <button onClick={updateUserInfo}>更新用户信息</button>
    </>
  )
}
  1. 值异步更新
    连续多次以相同的操作更新状态值时,React 内部会对传递过来的新值进行比较,值相同,则会屏蔽后续的更新行为,从而防止组件频繁渲染的问题。
    当修改state状态时,如果新值依赖于旧值(基于旧值计算得到新值)时,不要直接在外部计算,通过函数的形参拿到旧值并计算最终return新值。
javascript 复制代码
export const Count: React.FC = () => {
  const [count, setCount] = useState(() => 0)

  const add = () => {
    setCount(count + 1) // 两次操作后count值任然为1
    setCount(count + 1)
  }
  const addPrev = () => {
    setCount((c) => c + 1) // 传递了更新状态的函数进去,两次操作后count值为2
    setCount((c) => c + 1)
  }

  return (
    <>
      <h1>当前的 count 值为:{count}</h1>
      <button onClick={add}>+1</button>
      <button onClick={addPrev}>+1</button>
    </>
  )
} 
  1. 模拟组件的强制刷新
    useState 的状态发生了变化,就会触发函数组件的重新渲染,从而达到强制刷新的目的
javascript 复制代码
import React, { useState } from 'react'

export const FUpdate: React.FC = () => {
  const [, forceUpdate] = useState({})
  // 每次都会给 forceUpdate 传递一个新对象,从而触发组件的重新渲染
  const onRefresh = () => forceUpdate({})
  return (
    <>
      <button onClick={onRefresh}>点击强制刷新 --- {Date.now()}</button>
    </>
  )
}
相关推荐
LaughingZhu11 小时前
智能体经典范式构建:ReAct、Plan-and-Solve 与 Reflection
前端·react.js·前端框架
飞天狗12 小时前
长列表滚动卡顿怎么破:虚拟列表选型 + react-virtuoso 实战调优指南
react.js·性能优化
binbin_5215 小时前
React 井字棋教程:用一个小游戏理解组件和状态
前端·react.js·前端框架
张元清16 小时前
React useObjectUrl Hook:预览文件与 Blob,不留内存泄漏(2026)
javascript·react.js
真的想不出名儿19 小时前
Md编辑器整合-react
前端·react.js·编辑器
牛仔只喝牛奶1 天前
多端跨端技术选型:小程序 + H5 + App 的两栈拆分落地
react native·react.js
wear工程师2 天前
setState 到底是不是异步的?这题从 React 16 问到 18,标准答案早就变了
react.js·面试
wanghowie2 天前
LangGraph4j 落地(二)— ReAct 多步工具与 trace 扩展
前端·react.js·前端框架
csj502 天前
前端基础之《React(11)—state声明式》
前端·react.js
张元清2 天前
React useLocalStorage Hook:SSR 安全的持久化状态(2026)
javascript·react.js