React三大属性之一 state的一些简单的理解

什么是state

  React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。组件的任何UI改变,都可以从State的变化中反映出来;State中的所有状态都用于反映UI的变化,不应有多余状态。

  • state来自内部状态,是组件对象最重要的属性,其值是对象,可以包含多个数据
  • 可以通过更新组件的state来更新对应的页面显示(重新进行组件渲染),不必操作DOM
  • 当页面发生变化时,用state来记录页面变化

什么样的变量应该作为组件的state呢 

  1. 可以通过props从父组件中获取的变量不应该做为组件State。
  2. 这个变量如果在组件的整个生命周期中都保持不变就不应该作为组件State。
  3. 通过其他状态(State)或者属性(Props)计算得到的变量不应该作为组件State。
  4. 没有在组件的render方法中使用的变量不用于UI的渲染,那么这个变量不应该作为组件的State 。这种情况下,这个变量更适合定义为组件的一个普通属性。

 state的使用方法

1.初始化state

constructor(props) {
   super(props);
   this.state={
      key:value,
      ...
   }
}

2.更新state 

更新state调用以下方法

 this.setState({
     key:value
 }) ;

注意,千万不能直接this.state.key=XXX; 这样做不会重新渲染页面,另外setState()是异步的,也就是你调用了setState()之后,React就开始准备去更新了,中间计算会可能会有一定的延时。

比如说:

//反例 这样是错误的
this.setState({
  counter: this.state.count + this.props.add,
});
//正确的例子
this.setState((prevState, props) => ({
  counter: prevState.count + props.add
}))

3、调用diff算法

这一步是在2步的基础上的,setState()会触发diff算法最终确定是否要更新

setState的使用方法

先看一个例子,点击累加

import React, { Component } from "react";

class App extends Component {
  state = {
    count: 0,
  };
  AddCount = () => {
    this.setState({
      count: this.state.count + 1,
    });
  };
  handleAdd = () => {
    this.AddCount();
    this.AddCount();
    this.AddCount();
    console.log(this.state.count);
  };
  render() {
    return (
      <div>
        <button onClick={this.AddCount}>AddCount</button>
        <button onClick={this.handleAdd}>handleAdd</button>
        <br />
        <h1>{this.state.count}</h1>
      </div>
    );
  }
}

export default App;

这是我们初始界面

 当我们点击一下AddCount按钮 数字由0变为1 

而当我们点击handleAdd时,数字并未变成4,而是变为1

 当我们把AddCount函数改为

AddCount() {
  this.setState((prevState) => {
    return {count: prevState.count + 1}
  });
}

再次点击handleAdd,数字变为5,成功加3

 修改前后又有什么区别呢? 区别在于 传入一个更新函数,就可以访问当前状态值。 setState调用是 批量处理的,因此可以让更新建立在彼此之上,避免冲突。那为什么第一种方式就不可以呢?

setState为什么不会同步更新组件?

首先我们要知道

  • setState 不会立刻改变React组件中state的值.
  • setState 通过触发一次组件的更新来引发重绘.
  • 多次 setState 函数调用产生的效果会合并

重绘指的就是引起 React 的更新生命周期函数4个函数:

  • shouldComponentUpdate(被调用时this.state没有更新;如果返回了false,生命周期被中断,虽然不调用之后的函数了,但是state仍然会被更新)
  • componentWillUpdate(被调用时this.state没有更新)
  • render(被调用时this.state得到更新)
  • componentDidUpdate

如果说每一次setState调用都要走一编生命周期,这必然会导致效率问题。React会将setState的效果放在队列中,积攒着一次引发更新的过程,减少对 Virtual DOM 和 DOM 树的操作,用于提高性能。

查阅一些资料后发现,某些操作还是可以同步更新 this.state的

setState 什么时候会执行同步更新? 

在React中,如果是由React引发的事件处理(比如通过onClick引发的事件处理),调用 setState 不会同步更新 this.state,除此之外的setState调用会同步执行this.state。

所谓“除此之外”,指的是绕过React通过 addEventListener 直接添加的事件处理函数,还有通过setTimeout || setInterval 产生的异步调用。

简单一点说, 就是经过React 处理的事件是不会同步更新 this.state的. 通过 addEventListener || setTimeout/setInterval 的方式处理的则会同步更新

clipboard.png

 结语:本文借鉴了很多大佬博客中的思路,非常感谢大佬们的无私分享!愿互联网共享精神之光永远闪耀!

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来解答你的问题。 首先,我们需要在AutoComplete组件内部定义一个state来保存输入框的值,并且在输入框内部添加一个清空按钮。如果allowClear属性被设置为true,则显示该按钮;否则,隐藏该按钮。 接下来,我们需要在点击清空按钮时,清空输入框的值。这可以通过设置输入框的value为''来实现。 最后,我们需要在AutoComplete组件外部监听输入框的值变化,以便在值发生改变时更新state的值。 下面是一个使用React Hooks实现AutoComplete组件的示例代码,其中包括allowClear属性的实现: ```javascript import React, { useState, useEffect } from 'react'; const AutoComplete = ({ allowClear }) => { const [value, setValue] = useState(''); const handleInputChange = event => { setValue(event.target.value); }; const handleClearClick = () => { setValue(''); }; useEffect(() => { // 输入框值变化时更新state的值 // 这里可以写你需要的逻辑 }, [value]); return ( <div> <input type="text" value={value} onChange={handleInputChange} /> {allowClear && value && ( <button onClick={handleClearClick}>清空</button> )} </div> ); }; export default AutoComplete; ``` 在上面的代码中,我们在组件内部定义了一个state,即value,用来保存输入框的值。然后在输入框的onChange事件中,调用handleInputChange方法来更新value的值。 如果allowClear属性被设置为true且输入框的值不为空,就会显示一个清空按钮,当点击该按钮时,调用handleClearClick方法来清空输入框的值。 最后,我们使用了useEffect钩子来监听输入框值的变化,以便在值发生改变时更新state的值。如果你需要在输入框值变化时执行其他的逻辑,可以在useEffect中添加你需要的代码。 希望这个例子能够帮助你理解如何使用React Hooks手动实现AutoComplete的allowClear属性方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值