Extracted from https://github.com/facebook/react/issues/12643.

We're currently diff a host node in the complete phase even if it has bailed out in the begin phase. By itself, this just means we're doing a little bit more work than necessary. But it also has some observable effects. In particular, https://github.com/facebook/react/issues/13424 (which by itself would be very rare and probably not worth fixing) is made worse because we end up committing update to inputs from another component.

I have a fix for this in https://github.com/facebook/react/pull/13423. Filing this for posterity.
expect(container.firstChild.tagName).toBe('DIV');
    ReactDOM.render(<EmptyFragment />, container);
    expect(container.firstChild).toBe(null);
  });
  let svgEls, htmlEls, mathEls;
  const expectSVG = {ref: el => svgEls.push(el)};
  const expectHTML = {ref: el => htmlEls.push(el)};
  const expectMath = {ref: el => mathEls.push(el)};
  const usePortal = function(tree) {
    return ReactDOM.createPortal(tree, document.createElement('div'));
  };
  const assertNamespacesMatch = function(tree) {
    container = document.createElement('div');
    svgEls = [];
    htmlEls = [];
    mathEls = [];
    ReactDOM.render(tree, container);
    svgEls.forEach(el => {
      expect(el.namespaceURI).toBe('http://www.w3.org/2000/svg');
    });
    htmlEls.forEach(el => {
      expect(el.namespaceURI).toBe('http://www.w3.org/1999/xhtml');
    });
    mathEls.forEach(el => {
      expect(el.namespaceURI).toBe('http://www.w3.org/1998/Math/MathML');
    });
    ReactDOM.unmountComponentAtNode(container);
    expect(container.innerHTML).toBe('');
  };
  it('should render one portal', () => {