diff --git a/src/diff/children.js b/src/diff/children.js index 64e31b6328..e55fc97017 100644 --- a/src/diff/children.js +++ b/src/diff/children.js @@ -83,7 +83,7 @@ export function diffChildren( childVNode.type, childVNode.props, childVNode.key, - null, + childVNode.ref ? childVNode.ref : null, childVNode._original ); } else { @@ -244,14 +244,7 @@ function reorderChildren(childVNode, oldDom, parentDom) { if (typeof vnode.type == 'function') { oldDom = reorderChildren(vnode, oldDom, parentDom); } else { - oldDom = placeChild( - parentDom, - vnode, - vnode, - c, - vnode._dom, - oldDom - ); + oldDom = placeChild(parentDom, vnode, vnode, c, vnode._dom, oldDom); } } } diff --git a/src/diff/index.js b/src/diff/index.js index 270e789cfb..616bd93ae9 100644 --- a/src/diff/index.js +++ b/src/diff/index.js @@ -497,7 +497,9 @@ export function unmount(vnode, parentVNode, skipRemove) { if (options.unmount) options.unmount(vnode); if ((r = vnode.ref)) { - if (!r.current || r.current === vnode._dom) applyRef(r, null, parentVNode); + if (!r.current || r.current === vnode._dom) { + applyRef(r, null, parentVNode); + } } if ((r = vnode._component) != null) { diff --git a/test/browser/refs.test.js b/test/browser/refs.test.js index b697a4f526..a5962ea500 100644 --- a/test/browser/refs.test.js +++ b/test/browser/refs.test.js @@ -478,4 +478,69 @@ describe('refs', () => { render(, scratch); expect(el).to.not.be.equal(null); }); + + it('should not remove refs for memoized components keyed', () => { + const ref = createRef(); + const element =
hey
; + function App(props) { + return
{element}
; + } + + render(, scratch); + expect(ref.current).to.equal(scratch.firstChild.firstChild); + render(, scratch); + expect(ref.current).to.equal(scratch.firstChild.firstChild); + render(, scratch); + expect(ref.current).to.equal(scratch.firstChild.firstChild); + }); + + it('should not remove refs for memoized components unkeyed', () => { + const ref = createRef(); + const element =
hey
; + function App(props) { + return
{element}
; + } + + render(, scratch); + expect(ref.current).to.equal(scratch.firstChild.firstChild); + render(, scratch); + expect(ref.current).to.equal(scratch.firstChild.firstChild); + render(, scratch); + expect(ref.current).to.equal(scratch.firstChild.firstChild); + }); + + // TODO + it.skip('should properly call null for memoized components keyed', () => { + const calls = []; + const element =
calls.push(x)}>hey
; + function App(props) { + return
{element}
; + } + + render(, scratch); + render(, scratch); + render(, scratch); + expect(calls.length).to.equal(5); + expect(calls).to.deep.equal([ + scratch.firstChild.firstChild, + null, + scratch.firstChild.firstChild, + null, + scratch.firstChild.firstChild + ]); + }); + + it('should properly call null for memoized components unkeyed', () => { + const calls = []; + const element =
calls.push(x)}>hey
; + function App(props) { + return
{element}
; + } + + render(, scratch); + render(, scratch); + render(, scratch); + expect(calls.length).to.equal(1); + expect(calls[0]).to.equal(scratch.firstChild.firstChild); + }); });