React 组件状态

状态(state)是组件自己保存、会随时间变化的数据,比如计数器、输入框内容、开关状态。界面要"动"起来就必须让组件拥有状态,这也是 React 数据驱动视图的核心机制。

什么是 state

state 与 props 的区别在于:props 由父组件传入、组件内部只读;state 由组件自己管理,能通过专门的方法更新。state 一旦变化,React 会自动重新渲染相关界面。

函数组件:useState

useState 是 React 提供的 Hook,返回"当前值"和"更新函数"两个元素,可解构出来使用:

import { useState } from 'react'

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

  return (
    <div>
      <p>点击了 {count} 次</p>
      <button onClick={() => setCount(count + 1)}>加一</button>
    </div>
  )
}

count 初始值为 0,每次点击按钮 setCount 写入新值,界面自动刷新。

类组件:this.state 与 setState

类组件用 this.state 保存状态,且必须通过 this.setState() 更新,直接给 this.state 赋值不会生效:

import { Component } from 'react'

class Counter extends Component {
  constructor(props) {
    super(props)
    this.state = { count: 0 }
  }
  handleClick = () => {
    this.setState({ count: this.state.count + 1 })
  }
  render() {
    return (
      <div>
        <p>点击了 {this.state.count} 次</p>
        <button onClick={this.handleClick}>加一</button>
      </div>
    )
  }
}

setState 会自动合并对象字段,并触发一次重新渲染。

更新是"替换式"的:先复制再改

对象、数组这类引用类型状态,直接修改原数据不会触发渲染,必须创建新副本再交给 setState / setter:

const [user, setUser] = useState({ name: '小明', age: 18 })

// 错误:原地修改属性,界面不会更新
user.age = 19

// 正确:展开旧对象生成新对象
setUser({ ...user, age: 19 })

函数式更新:新值依赖旧值

同一事件里连续多次 setState 会被合并成一次渲染;当新值要基于旧值计算时,传入函数形式最稳妥:

setCount(c => c + 1)
setCount(c => c + 1)
// 连续调用两次,最终 count 比原来大 2(参数 c 始终是最新值)

小结:state 是组件的"记忆"。函数组件用 useState、类组件用 this.state/setState;修改对象状态务必先复制出新副本,依赖旧值时改用函数式更新,界面就会随状态自动刷新。

笔记加载中…