useState使用和原理


Hooks 是 React 16 中的特性,解決函數組件想使用類組件的一些特性。

關於更多 Hooks 介紹,請參考 React 官網[1]

useState
之前是在類組件中使用狀態通過 state 定義,大概代碼是這樣的。

 

import React from 'react';    
class Counter extends React.Component {    
  state = {    
    number: 0    
  }    
  handleClick = () => {    
    this.setState({    
      number: this.state.number + 1    
    })    
  }    
  render() {    
    return (    
      <>    
        <p>{this.state.number}</p>    
        <button    
          onClick={ this.handleClick }>    
          改數字    
        </button>    
      </>    
    );    
  }    
}    
function render() {    
  ReactDOM.render(<Counter />, document.getElementById('root'));    
}    
render()

 


但是函數組件沒有實例,也沒有狀態。函數組件使用狀態需要使用 useState 鈎子。

 

關於 useState 的用法是,需要傳入一個參數作為狀態的初始值,當函數執行后會返回兩個值,一個是當前狀態的屬性,一個是修改狀態的方法。

 

我們通過一個計數器的例子,當點擊按鈕表示狀態加1。

 

import React, {useState} from 'react';    
function Counter() {    
  const [    
    number,    
    setNumber    
  ] = useState(0)    
  return (    
    <>    
      <p>{number}</p>    
      <button    
        onClick={    
          () => setNumber(number + 1)    
        }    
      >    
        改數字    
      </button>    
    </>    
  )    
}    
function render() {    
  ReactDOM.render(<Counter />, document.getElementById('root'));    
}    
render()

 


現在我們已經掌握了它的用法,那么我們開始分析它的原理。

原理
我們需要寫一個 useState 方法,會返回當前狀態的屬性和設置狀態的方法,每當狀態改變之后,方法中會調用刷新視圖的 render 方法。

 

let memoizedState;    
function useState (initialState) {    
  memoizedState = memoizedState || initialState    
  function setState (newState) {    
    memoizedState = newState    
    render()    
  }    
  return [memoizedState, setState]    
}

 


再次嘗試之前的代碼,依然可以正常使用,但是當多個 useState 存在的時候就有問題了,只能變一個狀態了。

 

function Counter() {    
  const [    
    number,    
    setNumber    
  ] = useState(0)    
  const [    
    title,    
    setTitle    
  ] = useState('隨機標題')    
  return (    
    <>    
      <h1>{title}</h1>    
      <p>{number}</p>    
      <button    
        onClick={    
          () => setNumber(number + 1)    
        }    
      >    
        改數字    
      </button>    
      <button    
        onClick={    
          () => setTitle(`隨機標題${Math.random()}`)    
        }    
      >    
        改標題    
      </button>    
    </>    
  )    
}

 

現在我們需要優化我們的 Hooks ,解決多個 useState 同時使用的問題,當多個狀態存在的時候,我們需要使用數組保存狀態。

 

let memoizedStates = []    
let index = 0    
function useState (initialState) {    
  memoizedStates[index] = memoizedStates[index] || initialState    
  let currentIndex = index    
  function setState (newState) {    
    memoizedStates[currentIndex] = newState    
    render()    
  }    
  return [memoizedStates[index++], setState]    
}    
    
function Counter() {    
  const [    
    number,    
    setNumber    
  ] = useState(0)    
  const [    
    title,    
    setTitle    
  ] = useState('隨機標題')    
  return (    
    <>    
      <h1>{title}</h1>    
      <p>{number}</p>    
      <button    
        onClick={    
          () => setNumber(number + 1)    
        }    
      >    
        改數字    
      </button>    
      <button    
        onClick={    
          () => setTitle(`隨機標題${Math.random()}`)    
        }    
      >    
        改標題    
      </button>    
    </>    
  )    
}    
    
function render() {    
  index = 0    
  ReactDOM.render(<Counter />, document.getElementById('root'));    
}    
render()


現在已經完成了 useState 的基本原理,當你了解原理之后,使用 Hooks 就變得更加容易了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM