setState用法需要注意的点

1.关于setState 方法要注意的点

(1)参数及用法
  • react不能直接修改 this.state的值,需要使用this.setState()方法
  • setState()方法有两个参数
    • 参数1:是对象类型, key是this.state中的key值 ,val是修改后的数据
    • 参数2:是函数类型
      (1)查看数据是否已经更新 (2)可以获取到数据更新后的最新的DOM结构
  • 第一个参数有两种情况:
    -1. 第一个参数 为对象
    this.setState({
       isLiked: !this.state.isLiked
    })
    
    -2. 第一个参数 为方法
    this.setState( () =>{
       return{
        isLiked: !this.state.isLiked
      }  
    })
    
    当第一个参数为方法时,参数可以是上一次state的状态值和上一次props值
      this.setState((prevState,props)=>{
             return{
                  isLiked:!prevState.isLiked
              }
      })
    
(2)为什么要用setState方法?
  • 不能通过赋值直接修改state的值
    如:this.state.isLiked = '不喜欢'
    这种写法可以修改数据值,但是不会重新渲染界面

  • state的更新是异步的
    react为了优化性能,可能会将多个setState()合并成一个去更新,因为this.state 和 this.props是异步更新的,所以不能依据他们的值去计算下一个值。
    错误如下:

       this.setState({
          sum:this.state.count + this.props.num
       })
    

    为此,可以使用参数为方法,此方法有两个参数,第一个参数是前一个状态,第二个参数是传入的props值。
    正确如下:

        this.setState((prevState,props)=>{
             return{
                 sum:this.state.count + this.props.num
             }
          })
    
  • state的更新会被合并
    当你调用 setState(), React 将合并你提供的对象到当前的状态中。所以当State是一个多键值的结构时,可以单独更新其中的一个,此时会进行“差分”更新,不会影响其他的属性值。

(3)执行setState之后,就可以得到更新后的值吗?

可以通过一个例子得到结论:

class Lick extends Component {
    constructor(){
        super();
        this.state= {
            isLiked:false
        }
     }
     handleLikedClick = ()=>{
         this.setState(()=>{
            console.log('内部state值',this.state.isLiked);
            return {
                 isLiked: !this.state.isLiked
            }
        },()=>{
            console.log('回调state值',this.state.isLiked)
        });
        console.log('外部state值',this.state.isLiked)
    }
}

在修改setState执行之前,及之后,以及回调中可以得到此时的状态值

image.png

会发现,只有回调函数中才拿到了更新后的state值,所以也得出,若要在修改之后,在得到状态值,可以在setState方法的回调函数得到

(4)执行setState之后,会立马更新state的值吗(执行过程)?

看一看看下面的代码:

function incrementMultiple() {
    this.setState({count: this.state.count + 1});
    this.setState({count: this.state.count + 1});
    this.setState({count: this.state.count + 1});
}

直观上来看,当上面的 incrementMultiple 函数被调用时,组件状态的 count 值被增加了3次,每次增加1,那最后 count 被增加了3。但是,实际上的结果只给 state 增加了1。

事实上,setState 方法与包含在其中的执行是一个很复杂的过程
从 React 最初的版本到现在,也有无数次的修改。它的工作除了要更动 this.state 之外,还要负责触发重新渲染,这里面要经过 React 核心 diff 算法,最终才能决定是否要进行重渲染,以及如何渲染。而且为了批次与效能的理由,多个 setState 呼叫有可能在执行过程中还需要被合并,所以它被设计以延时的来进行执行是相当合理的。

原理图

在 React 的 setState 函数实现中,会根据一个变量isBatchingUpdates(是否批量更新) 判断是直接更新 this.state 还是放到队列中回头再说,而 isBatchingUpdates 默认是 false,也就表示 setState 会同步更新 this.state。
但是,有一个函数 batchedUpdates,这个函数会把 isBatchingUpdates 修改为 true,就会将this.state放入队列。
当 React 在调用事件处理函数之前就会调用这个 batchedUpdates,造成的后果,就是由 React 控制的事件处理过程 setState 不会同步更新 this.state

由 React 控制的事件处理过程 setState会异步更新 this.state
也就是说,在 React 控制之外的情况, setState 会同步更新 this.state

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容