挑战 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 预设值为0import 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
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
实作。
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 数字为同步
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 容易踩雷的一个点以及如何用传入的参数解决。