最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React state狀態(tài)屬性詳細講解

 更新時間:2022年09月30日 09:32:01   作者:月光曬了很涼快  
React將組件(component)看成一個狀態(tài)機(State Machines),通過其內(nèi)部自定義的狀態(tài)(State)和生命周期(Lifecycle)實現(xiàn)并與用戶交互,維持組件的不同狀態(tài)

1. 基本使用

要點:

  1. 成員屬性 state 它是一個特殊的屬性,它是當前類的私有數(shù)據(jù),只有在當前的組件中才能操作里面的數(shù)據(jù)
  2. 狀態(tài)( state )即數(shù)據(jù),是組件內(nèi)部的私有數(shù)據(jù),只能在組件內(nèi)部使用,和vue中data差不多,不過它沒有像vue中的data進行了數(shù)據(jù)劫持
  3. state的值是對象,表示一個組件中可以有多個數(shù)據(jù)
  4. 通過this.state來獲取狀態(tài),react 中沒有做數(shù)據(jù)代理
  5. 想要修改 state 數(shù)據(jù)值同時讓視圖更新則需要調(diào)用專用的方法 this.setState
  6. state 它是類的一個成員屬性
  7. state 中的數(shù)據(jù)可讀可寫的

使用:

import React, { Component } from 'react';
class App extends Component {
  // 初始化方式1
  // state = {
  //   num: 100
  // }
  // 初始化方式2
  constructor(props) {
    super(props);
    this.state = {
      num: 100
    }
  }
  addNum(evt, n = 1) {
    // 同步修改數(shù)據(jù),它不會觸發(fā)視圖更新
    this.state.num += n
    this.forceUpdate()
    console.log(this.state.num);
  }
  render() {
    return (
      <div>
        {/* 在視圖中讀取state中的數(shù)據(jù) */}
        <h3>{this.state.num}</h3>
        <button onClick={evt => this.addNum(evt, 2)}>累加</button>
      </div>
    );
  }
}
export default App;

2. 使用setState操作state數(shù)據(jù)

概述:

修改 state 中的 num 屬性數(shù)據(jù)的同時,讓視圖更新,用到專門用來修改 state 中數(shù)據(jù)的方法 setState。

語法:

# 語法1
this.setState({
    key:value
})
# 語法2  推薦
this.setState(state => {
    return {key:value}
})

使用:

import React, { Component } from 'react';
class App extends Component {
  state = {
    num: 100
  }
  addNum(evt, n = 1) {
    // 對象方式更新 批處理  => 數(shù)組【隊列】   虛擬dom比對
    // 它是一個異步操作
    this.setState({
      num: this.state.num + 1
    })
    console.log(this.state.num);
    // this.setState({
    //   num: this.state.num + 1
    // }, () => {
    //   // 回調(diào)函數(shù)中就可以得到最新的狀態(tài)數(shù)據(jù)
    //   console.log(this.state.num);
    // })
  }
  render() {
    return (
      <div>
        {/* 在視圖中讀取state中的數(shù)據(jù) */}
        <h3>{this.state.num}</h3>
        <button onClick={evt => this.addNum(evt, 2)}>累加</button>
      </div>
    );
  }
}
export default App;

注意:

注意執(zhí)行結(jié)果中,雖然視圖發(fā)生了更新,但是控制臺打印 state 中的數(shù)據(jù)并沒有發(fā)生改變,說明這里的更新數(shù)據(jù)是異步操作。

之所以是異步操作,是因為 React 在這里做了批處理。即當執(zhí)行多次修改數(shù)據(jù)的操作時,React 并不會立即執(zhí)行,而是將這些操作存入一個異步隊列中,然后再進行統(tǒng)一處理,這樣做可以提升性能。假如我現(xiàn)在要修改 3 次數(shù)據(jù),不用批處理需要更新視圖 3 次,而如果進行批處理的話,只需要更新視圖一次。更新視圖需要進行 dom 比對,只比 1 次顯然比比對 3 次性能更好。

關(guān)于 setState 方法(React 批處理)中的對象合并:

import React, { Component } from 'react';
class App extends Component {
  state = {
    num: 100
  }
  addNum(evt, n = 1) {
    this.setState({
      num: this.state.num + 1
    })
    this.setState({
      num: this.state.num + 2
    })
    this.setState({
      num: this.state.num + 3
    })
    console.log(this.state.num);
    // 函數(shù),它不會合并,它會依次執(zhí)行  == 建議多用函數(shù)方式,保證數(shù)據(jù)完整性
    // this.setState(state => ({
    //   num: state.num + 1
    // }))
    // this.setState(state => ({
    //   num: state.num + 2
    // }))
    // this.setState(state => ({
    //   num: state.num + 3
    // }))
    // console.log(this.state.num);//6
  }
  render() {
    return (
      <div>
        {/* 在視圖中讀取state中的數(shù)據(jù) */}
        <h3>{this.state.num}</h3>
        <button onClick={evt => this.addNum(evt, 2)}>累加</button>
      </div>
    );
  }
}
export default App;

從圖中運行結(jié)果可以看出,當我們多次修改數(shù)據(jù)時,視圖只針對最后一次修改作出渲染。這是因為在 React 批處理中(批處理隊列是一個集合,這里看作是一個對象),會進行對象合并。什么意思呢?首先對象的 key 值是唯一的,當 key 值 num 已經(jīng)存在時,再傳 num 會對對象中已經(jīng)存在的 num 進行修改,即對象中有效的 num 的值是最后一次操作:this.state.num + 3。

補充說明:批處理隊列的底層進行的是[...obj1,...obj2]的操作,所以重復(fù)的項只會出現(xiàn)一次。而函數(shù)方式的批處理進行的是[fn1,fn2...],所以會依次執(zhí)行。這里的解釋過于牽強和抽象,只是為了簡單理解和記憶,更加完整的闡述需要了解底層之后,再加深理解。

關(guān)于 setState 方法的同步操作:

react17 及之前版本,如果你把當前的操作不寫在合成事件中,則 setState 它就是同步的,react18全是異步的。

setState 在執(zhí)行的過程中,它會判斷當?shù)膱?zhí)行環(huán)境,如果為宏任務(wù)等,則它會立即執(zhí)行。

也就是說, setState 方法只要寫在合成事件處理方法中,它就是異步的;只要不寫在合成事件中,它都是同步。(僅限于 react17 及之前版本)

比如 setState 方法寫在宏任務(wù)中或者寫在原生事件中就是同步的。

例如下面這樣的寫法就是同步操作:

import React, { Component } from 'react';
class App extends Component {
  // setState它是同步的也是異步的
  // 只要寫在合成事件處理方法中,它就是異步
  // 只要不寫在合成事件中,它都是同步
  state = {
    num: 100
  }
  addNum(evt, n = 1) {
    setTimeout(() => {
      // 寫在宏任務(wù)中的setState它是同步的
      this.setState({
        num: this.state.num + 3
      })
      console.log(this.state.num);
    }, 0);
  }
  // 類似于vue中的mounted方法
  // componentDidMount() {
  //   // 寫在原生事件中它的setState也是同步的
  //   // document.onclick = () => {
  //   //   this.setState({
  //   //     num: this.state.num + 3
  //   //   })
  //   //   console.log(this.state.num);
  //   // }
  // 
  render() {
    return (
      <div>
        {/* 在視圖中讀取state中的數(shù)據(jù) */}
        <h3>{this.state.num}</h3>
        <button onClick={evt => this.addNum(evt, 2)}>累加</button>
      </div>
    );
  }
}
export default App;

3. 案例-toDoList

import React, { Component } from 'react';
class App extends Component {
  state = {
    todos: []
  }
  onEnter = evt => {
    if (evt.keyCode === 13) {
      let title = evt.target.value.trim()
      // 方案1
      // let todos = this.state.todos.concat({ id: Date.now(), title, done: false })
      // this.setState({ todos })
      // 方案2
      // this.state.todos.push({ id: Date.now(), title, done: false })
      // this.forceUpdate() // 這里也可以寫成這一句:this.setState({})
      // 如果你setState寫了一個空對象,則它會更新視圖一次
      // this.setState({})
      // 如果你寫了為null,setState不會做任何事件,相當于沒有調(diào)用
      // this.setState(null)
      // 方案3:更新數(shù)據(jù),推薦,確保數(shù)據(jù)的完整性
      this.setState(state => ({
        todos: [...state.todos, { id: Date.now(), title, done: false }]
      }), () => evt.target.value = '')
    }
  }
  del = tid => () => {
    this.setState(state => ({
      todos: state.todos.filter(({ id }) => id != tid)
    }))
  }
  delIndex = index => () => {
    this.state.todos.splice(index, 1)
    this.setState({})
  }
  render() {
    return (
      <div>
        <div>
          <input type="text" onKeyUp={this.onEnter} />
        </div>
        <hr />
        <ul>
          {
            this.state.todos.map((item, index) => (
              <li key={item.id}>
                <span>{item.title}</span>
                {/* 按 id 刪除 */}
                <span onClick={this.del(item.id)}>刪除</span>
                {/* 按索引刪除 */}
                <span onClick={this.delIndex(index)}>刪除</span>
              </li>
            ))
          }
        </ul>
      </div>
    );
  }
}
export default App;

注意:

setState 還有兩種擴展用法:

如果你setState寫了一個空對象,則它會更新視圖一次

this.setState({})

如果你寫了為null,setState不會做任何事件,相當于沒有調(diào)用

this.setState(null)

4. 案例-購物車

import React, { Component } from 'react';
class App extends Component {
  state = {
    carts: [
      { id: 1, name: '水果手機14', price: 1, num: 1 },
      { id: 2, name: '大米手機14', price: 1, num: 2 },
      { id: 3, name: '一般手機14', price: 1, num: 3 },
    ]
  }
  setNum = (n, index) => {
    // 方案1
    this.state.carts[index]['num'] += n
    if (this.state.carts[index]['num'] <= 1) this.state.carts[index]['num'] = 1
    if (this.state.carts[index]['num'] >= 5) this.state.carts[index]['num'] = 5
    this.setState({})
    // 方案2
    // this.setState(state => {
    //   state.carts[index]['num'] += n
    //   let carts = state.carts
    //   return { carts }// 同等于 return {carts:carts}
    // })
  }
  totalPrice = () => {
    return this.state.carts.reduce((p, c) => {
      p += c.num * c.price
      return p
    }, 0)
  }
  render() {
    return (
      <div>
        <table width='600' border='1'>
          <thead>
            <tr>
              <th>ID</th>
              <th>名稱</th>
              <th>價格</th>
              <th>數(shù)量</th>
            </tr>
          </thead>
          <tbody>
            {
              this.state.carts.map((item, index) => (
                <tr key={item.id}>
                  <td>{item.id}</td>
                  <td>{item.name}</td>
                  <td>{item.price}</td>
                  <td>
                    <button onClick={() => this.setNum(-1, index)}>---</button>
                    <span>{item.num}</span>
                    <button onClick={() => this.setNum(1, index)}>+++</button>
                  </td>
                </tr>
              ))
            }
          </tbody>
        </table>
        <hr />
        <h3>{this.totalPrice()}</h3>
      </div>
    );
  }
}
export default App;

到此這篇關(guān)于React state狀態(tài)屬性詳細講解的文章就介紹到這了,更多相關(guān)React state狀態(tài)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React服務(wù)端渲染原理解析與實踐

    React服務(wù)端渲染原理解析與實踐

    這篇文章主要介紹了React服務(wù)端渲染原理解析與實踐,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • React實現(xiàn)數(shù)字滾動組件numbers-scroll的示例詳解

    React實現(xiàn)數(shù)字滾動組件numbers-scroll的示例詳解

    數(shù)字滾動組件,也可以叫數(shù)字輪播組件,這個名字一聽就是非常普通常見的組件。本文將利用React實現(xiàn)這一組件,感興趣的小伙伴可以了解一下
    2023-03-03
  • React?Hooks--useEffect代替常用生命周期函數(shù)方式

    React?Hooks--useEffect代替常用生命周期函數(shù)方式

    這篇文章主要介紹了React?Hooks--useEffect代替常用生命周期函數(shù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 一文詳解React Redux設(shè)計思想與工作原理

    一文詳解React Redux設(shè)計思想與工作原理

    最近看項目中使用了?Redux,?便嘗試了解一波?Redux?的設(shè)計思想與工作原理,所以本文詳細的給大家介紹了Redux設(shè)計思想與工作原理,需要的朋友可以參考下
    2023-09-09
  • 如何使用React構(gòu)建一個高效的視頻上傳組件

    如何使用React構(gòu)建一個高效的視頻上傳組件

    本文介紹了如何使用React構(gòu)建一個高效的視頻上傳組件,包括基礎(chǔ)概念、常見問題與解決方案以及易錯點,通過實際代碼案例,展示了如何實現(xiàn)文件大小和格式驗證、上傳進度顯示等功能,并詳細解釋了跨域請求和并發(fā)上傳控制等技術(shù)細節(jié)
    2025-01-01
  • React中的axios模塊及使用方法

    React中的axios模塊及使用方法

    axios 是一個基于 promise 的 HTTP 庫,可以用在瀏覽器和 node.js 中,本文給大家分享React中axios模塊的使用方法,感興趣的朋友一起看看吧
    2022-03-03
  • React根據(jù)配置生成路由的示例代碼

    React根據(jù)配置生成路由的示例代碼

    React路由看似只能由Route組件包裹組件的結(jié)構(gòu)來構(gòu)成,但是其實也可以通過編寫路由數(shù)組配置然后通過數(shù)組循環(huán)來生成Route組件包裹組件的結(jié)構(gòu),所以本文給大家介紹了React根據(jù)配置生成路由的方法,需要的朋友可以參考下
    2024-11-11
  • React之useEffect缺少依賴警告問題及解決

    React之useEffect缺少依賴警告問題及解決

    這篇文章主要介紹了React之useEffect缺少依賴警告問題及解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • React?在非組件環(huán)境切換路由的方法

    React?在非組件環(huán)境切換路由的方法

    這篇文章主要介紹了React?在非組件環(huán)境切換路由的方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-10-10
  • 一文掌握React?組件樹遍歷技巧

    一文掌握React?組件樹遍歷技巧

    這篇文章主要為大家介紹了React?組件樹遍歷技巧的掌握,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04

最新評論

托里县| 绥德县| 盘锦市| 科技| 介休市| 明水县| 霍邱县| 咸丰县| 荆州市| 明光市| 孟州市| 尚志市| 吐鲁番市| 平阴县| 宜章县| 蛟河市| 霍林郭勒市| 视频| 英山县| 多伦县| 汉寿县| 松江区| 曲水县| 确山县| 凯里市| 民丰县| 鄂伦春自治旗| 霍州市| 灌云县| 平武县| 拜城县| 磐石市| 翁牛特旗| 兴义市| 县级市| 嘉定区| 邵阳县| 衡东县| 灵璧县| 同江市| 榆林市|