Skip to content

05.memo源码实现

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

react.js

js
import { REACT_ELEMENT, REACT_FORWARD_REF, REACT_MEMO, toVNode, shallowEqual } from './utils' ///

  function memo(type, compare = shallowEqual) { ///
    return {
      $$typeof: REACT_MEMO,
      type,
      compare
    }
  }
const React = {
    createElement,
    Component,
    createRef,
    forwardRef,
    PureComponent,
    memo///
}

utils.js

js
export const REACT_MEMO = Symbol('react.memo')

react-dom.js

js
import { REACT_ELEMENT, REACT_FORWARD_REF, REACT_MEMO, MOVE, CREATE, REACT_TEXT  } from './utils' //
function createDOM(VNode){
    // 1.创建元素 2.处理子元素 3.处理属性值
    //...
    if (type && type.$$typeof === REACT_MEMO) { //
        return getDomByMemoFunctionComponent(VNode);
    }
}
function deepDOMDiff(oldVNode, newVNode) {
    let diffTypeMap = {
        //...
        MEMO: oldVNode.type.$$typeof === REACT_MEMO //
    }
    let DIFF_TYPE = Object.keys(diffTypeMap).filter(key => diffTypeMap[key])[0]
    switch (DIFF_TYPE) {
        //....
        case 'MEMO':
            updateMemoFunctionComponent(oldVNode, newVNode) //
            break;
        default:
            break;
    }
}

function getDomByMemoFunctionComponent(vNode) { ///
    let { type, props } = vNode;
    let renderVNode = type.type(props);
    if (!renderVNode) return null;
    vNode.oldRenderVdom = renderVNode;
    return createDOM(renderVNode);
}

function updateMemoFunctionComponent(oldVNode, newVNode) { ///
    let { type } = oldVNode;
    if (!type.compare(oldVNode.props, newVNode.props)) {
        const oldDOM = findDomByVNode(oldVNode);
        const { type } = newVNode;
        let renderVNode = type.type(newVNode.props);
        updateDomTree(oldVNode.oldRenderVdom, renderVNode, oldDOM);
        newVNode.oldRenderVdom = renderVNode;
    } else {
        newVNode.oldRenderVdom = oldVNode.oldRenderVdom;
    }
}

基于 VitePress 构建