fix: fix functional updates

This commit is contained in:
Evan You 2018-11-13 01:07:13 -05:00
parent f5700245b0
commit ca91797c7f

View File

@ -79,6 +79,7 @@ export interface FunctionalHandle {
prev: VNode prev: VNode
next: VNode next: VNode
update: Autorun update: Autorun
container: RenderNode | null
} }
handleSchedulerError(err => handleError(err, null, ErrorTypes.SCHEDULER)) handleSchedulerError(err => handleError(err, null, ErrorTypes.SCHEDULER))
@ -266,7 +267,8 @@ export function createRenderer(options: RendererOptions) {
const handle: FunctionalHandle = (vnode.handle = { const handle: FunctionalHandle = (vnode.handle = {
prev: vnode, prev: vnode,
next: null as any, next: null as any,
update: null as any update: null as any,
container
}) })
const doMount = () => { const doMount = () => {
@ -282,6 +284,7 @@ export function createRenderer(options: RendererOptions) {
vnode.el = subTree.el as RenderNode vnode.el = subTree.el as RenderNode
}) })
mount(subTree, container, vnode as MountedVNode, isSVG, endNode) mount(subTree, container, vnode as MountedVNode, isSVG, endNode)
handle.next = vnode
if (__DEV__) { if (__DEV__) {
popWarningContext() popWarningContext()
} }
@ -310,19 +313,19 @@ export function createRenderer(options: RendererOptions) {
} }
function updateFunctionalComponent(handle: FunctionalHandle, isSVG: boolean) { function updateFunctionalComponent(handle: FunctionalHandle, isSVG: boolean) {
// mounted
const { prev, next } = handle const { prev, next } = handle
if (__DEV__) { if (__DEV__) {
pushWarningContext(next) pushWarningContext(next)
} }
const prevTree = prev.children as MountedVNode
const nextTree = (next.children = renderFunctionalRoot(next)) const nextTree = (next.children = renderFunctionalRoot(next))
queueEffect(() => { queueEffect(() => {
next.el = nextTree.el next.el = nextTree.el
}) })
patch( patch(
prev.children as MountedVNode, prevTree,
nextTree, nextTree,
platformParentNode(prev.el), handle.container as RenderNode,
next as MountedVNode, next as MountedVNode,
isSVG isSVG
) )
@ -567,7 +570,7 @@ export function createRenderer(options: RendererOptions) {
} else if (flags & VNodeFlags.COMPONENT_STATEFUL) { } else if (flags & VNodeFlags.COMPONENT_STATEFUL) {
patchStatefulComponent(prevVNode, nextVNode) patchStatefulComponent(prevVNode, nextVNode)
} else { } else {
patchFunctionalComponent(prevVNode, nextVNode) patchFunctionalComponent(prevVNode, nextVNode, container)
} }
} }
@ -605,11 +608,16 @@ export function createRenderer(options: RendererOptions) {
nextVNode.el = instance.$vnode.el nextVNode.el = instance.$vnode.el
} }
function patchFunctionalComponent(prevVNode: MountedVNode, nextVNode: VNode) { function patchFunctionalComponent(
prevVNode: MountedVNode,
nextVNode: VNode,
container: RenderNode
) {
const prevTree = prevVNode.children as VNode const prevTree = prevVNode.children as VNode
const handle = (nextVNode.handle = prevVNode.handle as FunctionalHandle) const handle = (nextVNode.handle = prevVNode.handle as FunctionalHandle)
handle.prev = prevVNode handle.prev = prevVNode
handle.next = nextVNode handle.next = nextVNode
handle.container = container
if (shouldUpdateComponent(prevVNode, nextVNode)) { if (shouldUpdateComponent(prevVNode, nextVNode)) {
queueJob(handle.update) queueJob(handle.update)