React 學習筆記之狀態(state)和生命周期

本文中我們同樣使用 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

相關