为何 React 官方推荐 setState 设定值而不使用 this.state设定?

挑战 React 第十三篇

上篇我们了解 state 可以在 component 里改变资讯且实作。

此篇将会用实作範例,证明修改 component 资料要用 setState 而不是使用 this.state 设定。

实作目标

按钮按一下,数字增加 1

实作範例 - 使用 this.state 更新数字

新增一个 Counter.js 档案

在 app.js 引入 counter.js

import React from 'react';import './App.css';import Counter from './Counter';function App() {  return (    <div className="App">      <Counter />    </div>  );}export default App;
设定 this.state 里的 count 预设值为0
import React, { Component } from 'react'class Counter extends Component {  constructor(props) {    super(props)      this.state = {       count: 0    }  }    render() {    return (      <div>        counter - {this.state.count}      </div>    )  }}export default Counter
先 yarn start 第二步骤结果

确认 UI 取得 state 预设值 0

加入按钮,按了按钮 + 1
import React, { Component } from 'react'class Counter extends Component {  constructor(props) {    super(props)      this.state = {       count: 0    }  }  //用this.state设定数字增加 1 ,并用console.log检查  increment() {    this.state.count = this.state.count + 1;    console.log(this.state.count);  }    render() {    return (      <div>        <div>counter - {this.state.count}</div>        <button onClick={() => this.increment()}>button</button>      </div>    )  }}export default Counter
yarn start 第四步骤

console.log里的数字确实有依照按钮次数增加,但画面上的数字仍然是0

用 this.state 设定后小结论

若直接用 this.state 设定值,UI 不会重新渲染,因此显示的值一直是预设值 0。

实作範例 - 使用 setState 更新数字

上面的实作範例,已得知 this.state 直接设定不会重新渲染,我们要改用 setState 实作。

用 setState 更新数字
  increment() {    this.setState({       count: this.state.count + 1     })    console.log(this.state.count);  }
yarn start 查看结果

修改写法后,确实有依照按钮按的次数更新数字

大家有发现 UI 的数字与 console.log 的数字不一致 ?

第一次按按钮:
UI更新数字后为 1,但 console.log数字为 0

第二次按按钮:
UI更新数字后为 2,但 console.log数字为 1

因为 setState 是非同步,而程式码显示的 console.log 数字为同步

用 callback value 查看状况,便会了解为什么数字不一致
increment() {    this.setState({       count: this.state.count + 1     },    // callback,确认 this.setState 后的 this.state.count 有 +1    () => {        console.log('callback value', this.state.count)    })    // 因 setState 非同步,没有立即取得更新后的值拿到预设值    console.log(this.state.count);  }

学习心得

一直到这篇学习,才了解 setState是非同步,而且从来没有点击过 setState 的说明写法,若有兴趣可查看以下程式码:

setState<K extends keyof S>(            state: ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) | (Pick<S, K> | S | null),            callback?: () => void        ): void;

看完才了解原来 setState 可以用 callback,甚至还可以传入参数,下篇会介绍 setState 容易踩雷的一个点以及如何用传入的参数解决。


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章