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.
const textContent = 'Hello world';
    const iframe = document.createElement('iframe');
    document.body.appendChild(iframe);
    const iframeDocument = iframe.contentDocument;
    iframeDocument.write(
      '<!DOCTYPE html><html><head></head><body><div></div></body></html>',
    );
    iframeDocument.close();
    const iframeContainer = iframeDocument.body.firstChild;
    let actualDocument;
    let textNode;
    spyOnDevAndProd(iframeContainer, 'appendChild').and.callFake(node => {
      actualDocument = node.ownerDocument;
      textNode = node;
    });
    ReactDOM.render(textContent, iframeContainer);
    expect(textNode.textContent).toBe(textContent);
    expect(actualDocument).not.toBe(document);
    expect(actualDocument).toBe(iframeDocument);
    expect(iframeContainer.appendChild).toHaveBeenCalledTimes(1);
  });
  it('should mount into a document fragment', () => {
    const fragment = document.createDocumentFragment();
    ReactDOM.render(<div>foo</div>, fragment);
    expect(container.innerHTML).toBe('');
    container.appendChild(fragment);
    expect(container.innerHTML).toBe('<div>foo</div>');
  });
});