05 Component State

这篇博客探讨了在React中如何正确使用State来更新DOM,强调了不应该直接修改State,而应该使用setState()。文章通过Clock组件示例解释了如何通过State实现定时更新。此外,还讲解了State更新的异步性质以及如何处理这种情况。同时,博客阐述了React组件间单向数据流的概念,强调每个组件的state是局部且只能向下传递,形成了一个自上而下的数据瀑布模型。

1. 使用State更新渲染DOM

  • 03 React element 更新渲染一节中提到
  • 通过设置定时器重复调用ReactDOM.redner()渲染是不推荐的做法
  • 本节将通过State编写有状态的组件完成之前效果
class Clock extends React.Component {
  constructor(props) {
    super(props)
    this.state = {date: new Date()}
  }
  componentDidMount() {
    this.timerID = setInterval(() => {
      this.tick(),
      1000
    })
  }
  componentWillUnmount() {
    clearInterval(this.timerId)
  }
  tick() {
    this.setState({
      date: new Date()
    })
  }
  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}</h2>
      </div>
    )
  }
}

ReactDOM.render() {
  <Clock />,
  document.getElementById('root')
}

2. State的正确使用

不要直接修改State

this.state.comment = 'hello' // Wrong
this.setState({comment: 'hello'}) // Correct

构造函数是唯一可以给this.state赋值的地方

State更新的浅合并

  • 在调用setState()时,React会把你提供的对象合并到当前的state
  • 这里的合并是浅合并,新值会完全替换当前值
this.state = {
  posts: [],
  comments: []
}
componentDidMount() {
  fetchPosts().then(res => {
    this.setState({
      posts: res.posts
    })
  })
  fetchComments().then(res => {
    this.setState({
      comments: res.comments
    })
  })
}

State的更新可能是异步的

  • 为了提升性能,React会把多个setState()调用合并成一个调用
  • 这就意味着this.props和this.state可能会异步更新
  • 所以不要依赖他们当前值来更新下一个状态
// 错误做法
this.setState({
  counter: this.state.counter + this.props.increment
})

// 正确做法
this.setState((state, props) => {
  counter: state.counter + props.increment
})

3. 理解组件的"单向"数据流

  • 组件之间不知道彼此是否有状态,也不关心
  • state之所以被称作局部的/封装的,是因为只可以自己访问
  • 组件可以将其state作为props传给其子组件
<FormattedDate date={this.state.date} />
  • FormattedDate组件会在props中接收参数date,但不知其来自父组件的state?输入
  • 上述通常被称作“自上而下单向”的数据流
  • 任何state总属于特定的组件,只能响应低于他们的组件
  • 将组件树想象成一个props的数据瀑布
  • 每一个组件的state就像是在任意一点给瀑布添加额外的水源,但只能往下流动
提供的引用内容中未提及“component.updateState”的相关信息,所以无法根据引用为你详细介绍其相关内容。 一般来说,在 React 里,更新组件状态常用的是 `this.setState`(类组件)和 `useState`(函数组件)。`this.setState` 用于类组件更新状态,它接收一个对象或者一个函数作为参数。当传入对象时,会将该对象的属性合并到组件的状态中;当传入函数时,函数接收前一个状态和当前的 props 作为参数,返回一个新的状态对象。示例如下: ```jsx class ExampleComponent extends React.Component { constructor(props) { super(props); this.state = { count: 0 }; } increment = () => { // 使用对象形式更新状态 this.setState({ count: this.state.count + 1 }); // 使用函数形式更新状态 this.setState((prevState, props) => ({ count: prevState.count + 1 })); } render() { return ( <div> <p>Count: {this.state.count}</p> <button onClick={this.increment}>Increment</button> </div> ); } } ``` 而在函数组件里,使用 `useState` 钩子来管理状态,调用它会返回一个有两个元素的数组,第一个元素是当前状态的值,第二个元素是用于更新状态的函数。示例如下: ```jsx import React, { useState } from 'react'; const ExampleComponent = () => { const [count, setCount] = useState(0); const increment = () => { setCount(count + 1); }; return ( <div> <p>Count: {count}</p> <button onClick={increment}>Increment</button> </div> ); }; ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值