Skip to content

Commit 5670ac8

Browse files
committed
Fix memory leak hotspots
- render: clear the root Fragment's props.children after commit so replaced vnode generations are not retained - unmount: clear component._globalContext with the other component references
1 parent 82ed24e commit 5670ac8

3 files changed

Lines changed: 28 additions & 1 deletion

File tree

src/diff/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,7 @@ export function unmount(vnode, parentVNode, skipRemove) {
654654
}
655655
}
656656

657-
r.base = r._parentDom = NULL;
657+
r.base = r._parentDom = r._globalContext = NULL;
658658
}
659659

660660
if ((r = vnode._children)) {

src/render.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ export function render(vnode, parentDom, replaceNode) {
6666

6767
// Flush all queued effects
6868
commitRoot(commitQueue, vnode, refQueue);
69+
70+
// The live children are tracked on _children after diffing.
71+
vnode.props.children = NULL;
6972
}
7073

7174
/**

test/browser/render.test.jsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,30 @@ describe('render()', () => {
240240
expect(scratch.innerHTML).to.equal('<span class="hello">Hello!</span>');
241241
});
242242

243+
it('should not keep the root input vnode in props.children', () => {
244+
let update;
245+
class App extends Component {
246+
constructor(props) {
247+
super(props);
248+
this.state = { value: 'a' };
249+
update = this.setState.bind(this);
250+
}
251+
252+
render() {
253+
return <button>{this.state.value}</button>;
254+
}
255+
}
256+
257+
render(<App />, scratch);
258+
let firstAppVNode = scratch._children._children[0];
259+
260+
update({ value: 'b' });
261+
rerender();
262+
263+
expect(scratch._children._children[0]).to.not.equal(firstAppVNode);
264+
expect(scratch._children.props.children).to.equal(null);
265+
});
266+
243267
it('should nest empty nodes', () => {
244268
render(
245269
<div>

0 commit comments

Comments
 (0)