Skip to content

Commit 4672611

Browse files
authored
fix case where we would omit the ref from reused vnodes (#3696)
* fix case where we would omit the ref from reused vnodes * add test for call ordering * correct tests * skip test for now
1 parent 1633907 commit 4672611

File tree

3 files changed

+70
-10
lines changed

3 files changed

+70
-10
lines changed

src/diff/children.js

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export function diffChildren(
8383
childVNode.type,
8484
childVNode.props,
8585
childVNode.key,
86-
null,
86+
childVNode.ref ? childVNode.ref : null,
8787
childVNode._original
8888
);
8989
} else {
@@ -244,14 +244,7 @@ function reorderChildren(childVNode, oldDom, parentDom) {
244244
if (typeof vnode.type == 'function') {
245245
oldDom = reorderChildren(vnode, oldDom, parentDom);
246246
} else {
247-
oldDom = placeChild(
248-
parentDom,
249-
vnode,
250-
vnode,
251-
c,
252-
vnode._dom,
253-
oldDom
254-
);
247+
oldDom = placeChild(parentDom, vnode, vnode, c, vnode._dom, oldDom);
255248
}
256249
}
257250
}

src/diff/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,9 @@ export function unmount(vnode, parentVNode, skipRemove) {
497497
if (options.unmount) options.unmount(vnode);
498498

499499
if ((r = vnode.ref)) {
500-
if (!r.current || r.current === vnode._dom) applyRef(r, null, parentVNode);
500+
if (!r.current || r.current === vnode._dom) {
501+
applyRef(r, null, parentVNode);
502+
}
501503
}
502504

503505
if ((r = vnode._component) != null) {

test/browser/refs.test.js

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,4 +478,69 @@ describe('refs', () => {
478478
render(<App />, scratch);
479479
expect(el).to.not.be.equal(null);
480480
});
481+
482+
it('should not remove refs for memoized components keyed', () => {
483+
const ref = createRef();
484+
const element = <div ref={ref}>hey</div>;
485+
function App(props) {
486+
return <div key={props.count}>{element}</div>;
487+
}
488+
489+
render(<App count={0} />, scratch);
490+
expect(ref.current).to.equal(scratch.firstChild.firstChild);
491+
render(<App count={1} />, scratch);
492+
expect(ref.current).to.equal(scratch.firstChild.firstChild);
493+
render(<App count={2} />, scratch);
494+
expect(ref.current).to.equal(scratch.firstChild.firstChild);
495+
});
496+
497+
it('should not remove refs for memoized components unkeyed', () => {
498+
const ref = createRef();
499+
const element = <div ref={ref}>hey</div>;
500+
function App(props) {
501+
return <div>{element}</div>;
502+
}
503+
504+
render(<App count={0} />, scratch);
505+
expect(ref.current).to.equal(scratch.firstChild.firstChild);
506+
render(<App count={1} />, scratch);
507+
expect(ref.current).to.equal(scratch.firstChild.firstChild);
508+
render(<App count={2} />, scratch);
509+
expect(ref.current).to.equal(scratch.firstChild.firstChild);
510+
});
511+
512+
// TODO
513+
it.skip('should properly call null for memoized components keyed', () => {
514+
const calls = [];
515+
const element = <div ref={x => calls.push(x)}>hey</div>;
516+
function App(props) {
517+
return <div key={props.count}>{element}</div>;
518+
}
519+
520+
render(<App count={0} />, scratch);
521+
render(<App count={1} />, scratch);
522+
render(<App count={2} />, scratch);
523+
expect(calls.length).to.equal(5);
524+
expect(calls).to.deep.equal([
525+
scratch.firstChild.firstChild,
526+
null,
527+
scratch.firstChild.firstChild,
528+
null,
529+
scratch.firstChild.firstChild
530+
]);
531+
});
532+
533+
it('should properly call null for memoized components unkeyed', () => {
534+
const calls = [];
535+
const element = <div ref={x => calls.push(x)}>hey</div>;
536+
function App(props) {
537+
return <div>{element}</div>;
538+
}
539+
540+
render(<App count={0} />, scratch);
541+
render(<App count={1} />, scratch);
542+
render(<App count={2} />, scratch);
543+
expect(calls.length).to.equal(1);
544+
expect(calls[0]).to.equal(scratch.firstChild.firstChild);
545+
});
481546
});

0 commit comments

Comments
 (0)