Skip to content

04.useState源码实现

代码演化过程见视频,这里只呈现相关代码:

hooks.js

js
import {emitUpdateForHooks } from './react-dom'
let states = [];
let hookIndex = 0

export function resetHookIndex(){
  hookIndex = 0
}

export function useState(initialValue) {
  states[hookIndex] = states[hookIndex] || initialValue;
  const currentIndex = hookIndex;
  function setState(newState) {
    states[currentIndex] = newState;
    emitUpdateForHooks();
  }
  return [states[hookIndex++], setState];
}

react-dom.js

js
import { resetHookIndex } from './hooks'
export let emitUpdateForHooks;
let isHooksUpdated = false
function render(VNode, containerDOM){
    // ...
    emitUpdateForHooks = () => {
        if (!isHooksUpdated) {
            isHooksUpdated = true;
            queueMicrotask(() => {
                isHooksUpdated = false;
                resetHookIndex() 
                updateDomTree(VNode, VNode, findDomByVNode(VNode));
            }) 
        }
    }
}
function getDomByFunctionComponent(VNode){
    let { type, props} = VNode
    let renderVNode = type(props)
    if(!renderVNode) return null
    VNode.oldRenderVNode = renderVNode /////
    let dom = createDOM(renderVNode)
    VNode.dom = dom
    return dom
}

function mountArray(children, parent){
    if(!Array.isArray(children)) return
    for(let i = 0; i < children.length; i++){
        if(!children[i]) {///
            children.splice(i, 1)///
            i--///
            continue///
        }////
        children[i].index = i;
        mount(children[i], parent)
    }
}

function updateChildren(parentDOM, oldVNodeChildren, newVNodeChildren) {
    //...
    newVNodeChildren.forEach((newVNode, index) => {
        newVNode.index = index
        let newKey = newVNode.key ? newVNode.key : index;
        let oldVNode = oldKeyChildMap[newKey];
        if (oldVNode) {
            ////////////////////
            updateDomTree(oldVNode, newVNode, findDomByVNode(oldVNode));/////
            // ....
        }
        // ...
    });

react.js

js
export * from './hooks' ////

基于 VitePress 构建