useState 實(shí)現(xiàn)原理

useState

  • 熟悉hooks的都知道,最常用的useState
  • 大概用法
function App() {
  const [x, setX] = useState(0)
  return <div>
    <h1>{x}</h1>
    <button onClick={() => setX(x + 1)}>+1</button>
  </div>
}

簡單的實(shí)現(xiàn)一個(gè)useState

  • 先模擬入?yún)⒑统鰠?/li>
const rootElement = document.getElementById("root");

const render = () => {
    ReactDOM.render(<App/>, root)
}
const useState = (initialValue) => {
    function setState(newState) {
      render()
    }
    return [state, setState]
}

function App() {
  const [n, setN] = useState(0);

  return (
    <div className="App">
      <h1>{n}</h1>
      <button onClick={() => setN(n + 1)}>+1</button>
    </div>
  );
}
  • 函數(shù)是存不住變量的,每次重新觸發(fā)就會(huì)出現(xiàn)一個(gè)新的值,所以我們的state需要一個(gè)全局的state。
  • 當(dāng)完成下面這個(gè),一個(gè)簡單的useState就完成了。
  • 可是它有bug,如果用到多個(gè)useState,他們共用的是一個(gè)state,那么就完蛋了,所以要改造一下。
let state;
const render = () => {
    ReactDOM.render(<App/>, root)
}
const useState = (initialValue) => {
    state = state === undefined ? initialValue : state
    function setState(newState) {
      state = newState
      render()
    }
    return [state, setState]
}
  • 把 state 初始化為一個(gè)數(shù)組,每次聲明一個(gè)useState時(shí)候就在存放一個(gè)值,并且用index去代表值。
  • 按照思路,每次觸發(fā)useState就要 index + 1,代表要在state數(shù)組里面添加一個(gè)值。
  • 每次重新setState重新渲染時(shí)候,就要index歸0,不然會(huì)無限增大state這個(gè)數(shù)組。
let state = []
let index = 0
const render = () => {
    index = 0
    ReactDOM.render(<App/>, root)
}
const useState = (initialValue) => {
    const currentIndex = index
    state[currentIndex] = state[currentIndex] === undefined 
        ? initialValue 
        : state[currentIndex]
    function setState(newState) {
      state[currentIndex] = newState
      render()
    }
    index = index + 1
    return [state[currentIndex], setState]
}

從簡單例子,深入一點(diǎn)了解。

  • 從簡單的例子我們可以看出,react 對(duì) useState 標(biāo)識(shí)是用index去記錄的,所以u(píng)seState不能寫在 if 里面,不然順序就識(shí)別不了,我們常常看到這么一行報(bào)錯(cuò)。

    就是這個(gè)原因,當(dāng)然react內(nèi)部的index是使用鏈表去實(shí)現(xiàn)的。

  • 那么,每個(gè)組件的state聲明在哪里? 其實(shí)它就聲明在虛擬dom里頭。



    每次聲明一個(gè)組件時(shí)候,組件內(nèi)部就會(huì)生成一個(gè) memoizedState 和 index (真正名稱自己去查看)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容