diff --git a/packages/react-dom/src/__tests__/ReactIdentity-test.js b/packages/react-dom/src/__tests__/ReactIdentity-test.js index 47814fc39d18e..5c25daf7d8f30 100644 --- a/packages/react-dom/src/__tests__/ReactIdentity-test.js +++ b/packages/react-dom/src/__tests__/ReactIdentity-test.js @@ -10,18 +10,20 @@ 'use strict'; let React; -let ReactDOM; +let ReactDOMClient; let ReactTestUtils; +let act; describe('ReactIdentity', () => { beforeEach(() => { jest.resetModules(); React = require('react'); - ReactDOM = require('react-dom'); + ReactDOMClient = require('react-dom/client'); ReactTestUtils = require('react-dom/test-utils'); + act = require('internal-test-utils').act; }); - it('should allow key property to express identity', () => { + it('should allow key property to express identity', async () => { let node; const Component = props => (
(node = c)}> @@ -31,15 +33,20 @@ describe('ReactIdentity', () => { ); const container = document.createElement('div'); - ReactDOM.render(, container); + const root = ReactDOMClient.createRoot(container); + await act(async () => { + root.render(); + }); const origChildren = Array.from(node.childNodes); - ReactDOM.render(, container); + await act(async () => { + root.render(); + }); const newChildren = Array.from(node.childNodes); expect(origChildren[0]).toBe(newChildren[1]); expect(origChildren[1]).toBe(newChildren[0]); }); - it('should use composite identity', () => { + it('should use composite identity', async () => { class Wrapper extends React.Component { render() { return {this.props.children}; @@ -47,25 +54,27 @@ describe('ReactIdentity', () => { } const container = document.createElement('div'); + const root = ReactDOMClient.createRoot(container); let node1; let node2; - ReactDOM.render( - - (node1 = c)} /> - , - container, - ); - ReactDOM.render( - - (node2 = c)} /> - , - container, - ); - + await act(async () => { + root.render( + + (node1 = c)} /> + , + ); + }); + await act(async () => { + root.render( + + (node2 = c)} /> + , + ); + }); expect(node1).not.toBe(node2); }); - function renderAComponentWithKeyIntoContainer(key, container) { + async function renderAComponentWithKeyIntoContainer(key, root) { class Wrapper extends React.Component { spanRef = React.createRef(); render() { @@ -76,36 +85,41 @@ describe('ReactIdentity', () => { ); } } - - const instance = ReactDOM.render(, container); - const span = instance.spanRef.current; + const wrapperRef = React.createRef(); + await act(async () => { + root.render(); + }); + const span = wrapperRef.current.spanRef.current; expect(span).not.toBe(null); } - it('should allow any character as a key, in a detached parent', () => { + it('should allow any character as a key, in a detached parent', async () => { const detachedContainer = document.createElement('div'); - renderAComponentWithKeyIntoContainer("<'WEIRD/&\\key'>", detachedContainer); + const root = ReactDOMClient.createRoot(detachedContainer); + await renderAComponentWithKeyIntoContainer("<'WEIRD/&\\key'>", root); }); - it('should allow any character as a key, in an attached parent', () => { + it('should allow any character as a key, in an attached parent', async () => { // This test exists to protect against implementation details that // incorrectly query escaped IDs using DOM tools like getElementById. const attachedContainer = document.createElement('div'); + const root = ReactDOMClient.createRoot(attachedContainer); document.body.appendChild(attachedContainer); - renderAComponentWithKeyIntoContainer("<'WEIRD/&\\key'>", attachedContainer); + await renderAComponentWithKeyIntoContainer("<'WEIRD/&\\key'>", root); document.body.removeChild(attachedContainer); }); - it('should not allow scripts in keys to execute', () => { + it('should not allow scripts in keys to execute', async () => { const h4x0rKey = '">
; const instance1 = ; - let wrapped = ; - - wrapped = ReactDOM.render(wrapped, document.createElement('div')); - const div = ReactDOM.findDOMNode(wrapped); + const container = document.createElement('div'); + const root = ReactDOMClient.createRoot(container); + const wrappedRef = React.createRef(); + await act(async () => { + root.render( + , + ); + }); + const div = container.firstChild; - const beforeA = div.childNodes[0]; - const beforeB = div.childNodes[1]; - wrapped.swap(); - const afterA = div.childNodes[1]; - const afterB = div.childNodes[0]; + const beforeA = div.firstChild; + const beforeB = div.lastChild; + await act(async () => { + wrappedRef.current.swap(); + }); + const afterA = div.lastChild; + const afterB = div.firstChild; expect(beforeA).toBe(afterA); expect(beforeB).toBe(afterB); @@ -264,7 +285,7 @@ describe('ReactIdentity', () => { }).not.toThrow(); }); - it('should throw if key is a Temporal-like object', () => { + it('should throw if key is a Temporal-like object', async () => { class TemporalLike { valueOf() { // Throwing here is the behavior of ECMAScript "Temporal" date/time API. @@ -277,15 +298,15 @@ describe('ReactIdentity', () => { } const el = document.createElement('div'); - const test = () => - ReactDOM.render( -
- -
, - el, - ); - expect(() => - expect(test).toThrowError(new TypeError('prod message')), + const root = ReactDOMClient.createRoot(el); + await expect(() => + expect(() => { + root.render( +
+ +
, + ); + }).toThrowError(new TypeError('prod message')), ).toErrorDev( 'The provided key is an unsupported type TemporalLike.' + ' This value must be coerced to a string before using it here.',