前端入門React 三大屬性之一 State

理解什麼是 state ?

首先 咱們用最通俗易懂的話來理解, 好比 每一個人都有本身的狀態 , 每一個人的狀態 都會影響 他的行爲,react

那麼, 咱們將這句話放到 react 中去理解,把人看做是 組件,組件也有本身的狀態,組件的狀態會影響api

它的頁面。markdown

咱們在遊覽各大網頁時,會發現 網頁上有一些數據,如我的信息 帳號 以及一些新聞列表等等。 這些都app

是數據, 咱們將這些數據放在了頁面上,那麼是什麼驅動着頁面的改變呢? 是數據。 這時候咱們只須要函數

將數據 放入狀態 ( state ) 中 ,咱們去更改狀態 頁面也會隨之變化。this

  1. 首先咱們用腳手架建立一個 react 項目

r1.jpg

  1. 啓動 項目 進入 src / app.js 修改爲以下文件
import React, { Component } from 'react'
​
export default class App extends Component {
  render() {
    console.log(this)
    return (
      <div>
        app組件
      </div>
    )
  }
}
複製代碼
  1. 打開 控制檯能夠看見 以下

r2.jpg

  1. 咱們在 render() 方法中 打印了 this 能夠看見在這個組件的實例對象上面。已經有一個 state 了 ( 這就是react 給你準備好的狀態 )

如今咱們回到 第一個問題 理解什麼是 state ?spa

1 . state 是組件對象最重要的屬性 ,值是對象 ( 裏面能夠包含多個 key : value 的 組合 ) 雖然在初始化看到的是null , 在react以前的版本中 仍是一個 { }3d

2 . 組件被稱之爲狀態機 , 經過更新組件裏的 state 來更新對應的頁面顯示 ( 從新渲染組件 )code

須要注意的地方 : 因有函數時組件與類式組件 react 將狀態放到了 實例對象裏 函數時組件 連this都沒有 哪兒來的 狀態呢? 在考慮初學者未接觸到 hooksorm

咱們 先從 類 組件來講。

初始化 state

  1. 首先 咱們新建一個組件 以下 :
import React, { Component } from 'react'
​
export default class App extends Component {
​
  constructor(props) {
    super(props)
    // 初始化狀態
    this.state = {
      isHot: true
    }
  }
​
  render() {
    console.log(this)
    return (
      <div>123</div>
    )
  }
}
複製代碼

咱們在 類 中 放了一個 構造器 constructor , 調用了 super ( 傳遞的props 不在本章見作詳細說明 咱們先寫上 )

  1. 在構造器裏 咱們改變了實例對象裏面的 state 這時候 咱們啓動項目 打開控制檯

r3.jpg

能夠看見 咱們初始化好了 一個 狀態 key : isHot value:true

  1. 讀取狀態 咱們將 render 方法中的代碼改成 以下:
render() {
    console.log(this.state)
    return (
      <h2>今每天氣很{this.state.isHot ? '炎熱' : '寒冷'}</h2>
    )
  }
​
複製代碼

打開頁面與控制檯 咱們查看一下

r4.jpg

React 中的事件綁定

須要注意的是 原生js 中的 onclick , onblur ... 等等 在 React 中 所有改成 onClick onBlur 這種小駝峯的寫法

  1. 接下來 咱們修改 代碼以下
import React, { Component } from 'react'
​
export default class App extends Component {
​
  constructor(props) {
    super(props)
    this.state = {
      isHot: true
    }
  }
​
  render() {
    return (
      <h2 onClick={ clickTitle() }>今每天氣很{this.state.isHot ? '炎熱' : '寒冷'}</h2>
    )
  }
}
​
function clickTitle() {
  console.log('標題被點擊了');
}
複製代碼
  1. 咱們打開控制檯能夠看見 咱們尚未點擊 , 控制檯就已經打印了 。

r5.jpg

咱們能夠思考一下爲何 ?

onClick = { clickTitle() } 同等於 onClick = { 函數調用的返回值 }

咱們將返回值 直接給到了 onClick 他就自動的去給你點了

咱們將 onClick = { clickTitle() } 後面的調用給去掉 改成 onClick = { clickTitle }

從新回到頁面 咱們能夠看到 已經能夠進行正常的點擊操做了

類方法中的 this

此處 咱們接着上一個小節中的內容 繼續 。

我須要 點擊標題的時候 讓炎熱變成寒冷 這個時候怎麼去處理? 咱們須要將代碼修改爲 以下:

import React, { Component } from 'react'
​
export default class App extends Component {
​
  constructor(props) {
    super(props)
    this.state = {
      isHot: true
    }
  }
​
  clickTitle() {
    console.log('標題被點擊了');
  }
​
  render() {
    return (
      <h2 onClick={ this.clickTitle }>今每天氣很{this.state.isHot ? '炎熱' : '寒冷'}</h2>
    )
  }
}
複製代碼

首先 咱們只須要將 函數從實例的外面 放到實例的裏面去

那麼 clickTitle 這個方法放在哪兒了呢?

他放在了類的實例對象上,供實例使用

r6.jpg

因此 咱們須要在

<h2 onClick={ this.clickTitle }>今每天氣很{this.state.isHot ? '炎熱' : '寒冷'}</h2>
複製代碼

這句話中 改爲 this.clickTitle

啓動項目 發現 標題依然是能夠被點擊的

接下來 咱們將函數內的代碼改成

clickTitle() {
    console.log(this.state.isHot);
}
複製代碼

這時 控制檯就直接報錯了

r7.jpg

咱們再去打印 this 時會發現 this 是 undefined

咱們能夠知道 constructor 和 render 中的 this 都是指組件的實例對象 ,那麼本身定義的clickTitle 裏的this爲何是undefined呢

r8.jpg

首先咱們要了解到 只有當 clickTitle 這個方法 是組件的實例對象去調用的時候 它裏面的 this 纔是clickTitle的實例對象

constructor 裏的 this 必定是當前實例的 實例對象 是一個固定的東西

注意: 咱們須要知道的是 clickTitle 在調用的時候 並非App這個實例對象去調用他的

這時候 再思考一個問題 既然不是 這個實例去調用他的 那 this 爲何是 undefined 不是 window呢 ?

注意:在類中 所定義的方法 它會自動的去在你所定義的方法裏面 開啓嚴格模式 開啓嚴格模式後 this 就是 undefined 是 類 自動幫你開啓的

解決類中 this 的指向問題

在constructor 裏 加一段代碼 以下

constructor(props) {
    super(props)
    this.state = {
      isHot: true
    }
   // 解決 this 的指向問題
    this.clickTitle = this.clickTitle.bind(this)
  }
複製代碼

這個時候 咱們去控制檯 點擊標題 查看一下

r9.jpg

this.clickTitle = this.clickTitle.bind(this) 這一段代碼 自己是一個賦值語句 咱們在實例對象自己加了一個方法 這個方法從那兒來的呢? 是從原型上來的

r10.jpg

React 中 setState 的使用

此處 咱們接着上一個小節中的內容 繼續 。

咱們將函數體的內容改成 以下 :

clickTitle() {
    this.state.isHot = !this.state.isHot
  }
複製代碼

運行項目後 發現 點擊標題依然不能改變標題的內容

咱們打印 函數裏的 this.state.isHot

r11.jpg

會發現 isHot的值確實在改變 可是爲何頁面不更新呢

嚴重注意: state( 狀態 ) 不可直接更改, this.state.isHot = !this.state.isHot 這一行是錯誤的寫法

此處 咱們須要藉助 一個內置的 api 去更改state的值 setState() 。 咱們在函數體內打印 this 能夠找到

r12.jpg 在函數體內修改以下代碼 :

clickTitle() {
  this.setState({ isHot: !this.state.isHot })
}
複製代碼

這時 咱們點擊 頁面中的 標題 就能夠進行切換了

注意: 修改state的值 必須使用 setState 來修改, 且 修改是一個合併的動做 並非直接替換 setState調用幾回 render 這個方法就會調用幾回 能夠本身打印試試

State 的簡寫方式

將代碼改爲 以下:

import React, { Component } from 'react'
​
export default class App extends Component {
​
  // constructor(props) {
  //   super(props)
  //   this.state = {
  //   }
  //   this.clickTitle = this.clickTitle.bind(this)
  // }
​
  state = {
    isHot: true
  }
​
  // clickTitle() {
  //   this.setState({ isHot: !this.state.isHot })
  // }
​
  clickTitle = () => {
    this.setState({ isHot: !this.state.isHot })
  }
​
  render() {
    return (
      <h2 onClick={this.clickTitle}>今每天氣很{this.state.isHot ? '炎熱' : '寒冷'}</h2>
    )
  }
}
複製代碼

此處 咱們將 state 從 constructor 直接拿出來

在類中 , 咱們直接寫一個賦值的語句 至關於 咱們在 APP 這個實例對象上 新加了一個屬性 屬性的名字 是 state 它的值是 { isHot:true }

而後 在將 this.clickTitle = this.clickTitle.bind(this) 給註釋掉

一樣 咱們在實例對象上 新增了一個方法 爲 clickTitle 值 是一個 箭頭 函數 這樣就解決掉了 this 的指向問題 避免在 constructor 頻繁的 使用bind 綁定this

將這兩行 註釋掉了之後 咱們徹底能夠將 constructor 這個構造器 給註釋掉, 由於咱們沒有在裏面寫任何的內容

如下爲完整代碼

import React, { Component } from 'react'
​
export default class App extends Component {
  //初始化狀態
  state = {
    isHot: true
  }
  //自定義方法 須要採用 賦值語句的形式 + 箭頭函數
  clickTitle = () => {
    this.setState({ isHot: !this.state.isHot })
  }
  //渲染
  render() {
    return (
      <h2 onClick={this.clickTitle}>今每天氣很{this.state.isHot ? '炎熱' : '寒冷'}</h2>
    )
  }
}
複製代碼
相關文章
相關標籤/搜索