React 學習筆記之狀態(state)和生命周期
- 2020 年 1 月 5 日
- 筆記
本文中我們同樣使用 React 官方教程中的一個時鐘的案例來給大家講解 state 的作用及時生命周期中的一些介面函數。案例可能與官方不是很匹配,是因為我經過刻意修改,為的是以國人理解的方式再重新梳理一遍,讓大家更容易理解。
顯示一個時間
import React, { Component } from 'react'; import ReactDOM from 'react-dom'; class Clock extends Component { render() { return ( <div> <h1>{new Date().toLocaleTimeString()}</h1> </div> ); } } ReactDOM.render( <Clock />, document.getElementById('root') );
以上程式碼實現了一個 Clock 的組件,該組件很簡單的在一個 h1 標籤中顯示了當前時間,但是你會發現這個時間是個靜止的時間,很明顯,它沒什麼實際作用,我們要想辦法讓它動起來。所以我們就要用到 state + 生命周期中提供的一些介面來實現這個功能。
使用 state 來顯示時鐘
import React, { Component } from 'react'; import ReactDOM from 'react-dom'; class Clock extends Component { constructor(props) { super(props); this.state = {date: new Date()}; } render() { return ( <div> <h1>{this.state.date.toLocaleTimeString()}</h1> </div> ); } } ReactDOM.render( <Clock />, document.getElementById('root') );
經過改造後,我們僅僅是在構造函數(constructor)中給 this.state 賦了一個初值。然後在 render 中顯示了 this.state.date 中的內容。但同樣,這個時間還是靜止的,我們要想辦法讓它一秒變一次。那麼接下來就用到了生命周期相關的介面。
使用聲明周期相關介面
import React, { Component } from 'react'; import ReactDOM from 'react-dom'; class Clock extends Component { constructor(props) { super(props); this.state = {date: new Date()}; } // 組件已經掛載 componentDidMount() { this.timerId = setInterval( () => this.tick(), 1000 ); } // 組件即將被移除 componentWillUnMount() { clearInterval(this.timerId); } // 每一秒設置一次 state 中 date 的值 tick() { this.setState({ date: new Date() }); } render() { return ( <div> <h1>{this.state.date.toLocaleTimeString()}</h1> </div> ); } } ReactDOM.render( <Clock />, document.getElementById('root') );
我們增加了兩個函數,一個是 componentDidMount
,該函數會在組件已經載入完畢後被調用。另外一個是 componentWillUnMount
,該函數會在組件即將被銷毀時調用。
我們在 componentDidMount 函數中增加了一個定時器,每一秒調用一次 tick 函數,這個函數是我們新實現的,目的就是調用一下 setState
方法來設置 state 裡面的值,當 state 裡面的值改變時,控制項上使用的 state.date.toLocaleTimeString() 的值也就會跟隨變更。這樣我們就實現了時間的自動更新。最後在組件即將被銷毀時,我們有調用了 clearInterval 清除了定時器。最終時間就會在介面上自動變更了。
這就是 state 的作用,大家可以想一想,如果在傳統 web 前端技術中,你想實現這樣一個功能要如何實現呢?對比 React 有什麼優勢或者缺點嗎?
注意事項
不可以直接修改狀態
// Wrong this.state.comment = 'Hello';
必須使用 setState 方法
// Correct this.setState({comment: 'Hello'});
你唯一能給其賦初值的地方就是構造函數。
setState 是非同步的
參考該文章:https://segmentfault.com/a/1190000007454080