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;
}
}