天天看點

React中setState方法詳細講解

setState跟新資料是同步還是異步?
setState跟新資料是異步的。
如何用代碼表現出來是異步的。
點選按鈕更新資料,然後去列印這個值看一下      
setState跟新資料是異步的
class Father extends React.Component{
  state = {
   num:0
  }
  addHandler = () => { 
    this.setState({
      num: 100
    })
    console.log('state中的值',this.state.num)
  }
  render() { 
    return (
      <div>
        <button onClick={this.addHandler}>新增</button>
        <p>顯示的值 {this.state.num }</p>
      </div>
    )
  }
}
ReactDOM.render(
  <Father></Father>,
  document.getElementById('root')
)      
React中setState方法詳細講解
我們發現
當我們使用setState更新資料時候,
然後立刻去擷取更新後的值,我們發現不是我們更新後的值。
而是更新前的值。
這就說明了setState跟新資料是異步的      
是以需要注意的點
由于 setState 跟新資料是異步的。
是以 setState 後面的代碼不要依賴于setState前面的。      
同一個方法多次調用 setState會怎麼樣
class Father extends React.Component{
  state = {
   num:0
  }
  addHandler = () => { 
    <!-- 第一調用 -->
    this.setState({
      num: this.state.num+1
    })
    console.log('state中的值', this.state.num)
    
    <!-- 第二次調用 -->
    this.setState({
      num: this.state.num + 1
    })
    console.log('state中的值', this.state.num)
  }
  render() { 
    return (
      <div>
        <button onClick={this.addHandler}>新增</button>
        <p>顯示的值 {this.state.num }</p>
      </div>
    )
  }
}      
React中setState方法詳細講解
我們的結論
在同一個方法中我們調用了兩次setState.
但是最後界面上顯示的不是2;0+1+1=2
而是顯示的1
也就是說雖然多次調用setState,但是最終隻會執行一次。 
是以隻會觸發一次渲染界面。是以界面上顯示的是1
由于界面隻觸發一次,是以render函數也隻會觸發一次      
為什麼多次調用setState最終隻會觸發一次渲染界面
這樣做的目的是為了性能的考慮。
比如說你寫了一個循環,循環了1000次;
設計的時候如果讓setState執行1000次;
這樣太浪費性能了。
完全可以讓開發者将最後的結果進行展示。

是以React并不會将setState執行1000次
而是隻會執行一次。 render函數也隻會執行一次。      
非要讓setState多次執行怎麼辦?
有沒有這樣的場景?
第二次的setState需要依賴第一次的setState的結果
舉個簡單的例子:第一次數字從0變為1,第二次1變為10
這個時候我們怎麼辦了?
比着急,有解決的辦法      
setState 推薦文法
setState((state, props) => { 
    參數state,表示最新的state
    參數props,表示最新的props
})
需要的是這種文法也是異步的哈      
使用推薦文法實作setState多次執行
class Father extends React.Component{
  state = {
   num:0
  }
  addHandler = () => { 
    <!-- 在這個方法中我們多次調用了setState  -->
    this.setState((state, props) => { 
      // state 
      // props
      return {
        num: state.num+1
      }
    })
    this.setState((state, props) => {
      // state 
      // props
      return {
        num: state.num + 10
      }
    })
    console.log('state中的值', this.state.num)
  }
  render() { 
    return (
      <div>
        <button onClick={this.addHandler}>新增</button>
        <p>顯示的值 {this.state.num }</p>
      </div>
    )
  }
}      
React中setState方法詳細講解
setState第二個參數的誕生
剛剛我們在前面發現console.log擷取的值
不是資料更新的後的值。
而是初始值。我們也說了
由于 setState 跟新資料是異步的。
是以 setState 後面的代碼不要依賴于setState前面的。
如果我們想擷取 setState更新後的值怎麼辦了?
這個時候我們就需要使用setState的第二個參數。

setState第二個參數的場景
在狀态更新完成(界面完成重新渲染)後立刻執行某一個操作
ps:需要注意的的是不可以不會頁面中的dom
ps:需要注意的的是不可以不會頁面中的dom
this.setState(
    (state, props) => {
        return {}
    },
    ()=>{
        console.log('界面完成重新渲染)後立刻執行某一個操作')
    }
)      
setState第二個參數的使用
class Father extends React.Component{
  state = {
   num:0
  }
  addHandler = () => { 
    this.setState(
      (state, props) => {
        return {
          num: state.num + 1
        }
      },
      () => { 
        console.log('擷取setState跟新後的值', this.state.num)
        console.log('dom節點',document.getElementById('#name') )
        console.log('cont', document.title)
      }
    )
  }
  render() { 
    return (
      <div>
        <button onClick={this.addHandler}>新增</button>
        <p id='name'>顯示的值 {this.state.num }</p>
      </div>
    )
  }
}
ReactDOM.render(
  <Father></Father>,
  document.getElementById('root')
)      
React中setState方法詳細講解

遇見問題,這是你成長的機會,如果你能夠解決,這就是收獲。

繼續閱讀