diff --git a/packages/react-dom/src/__tests__/ReactDOMFiber-test.js b/packages/react-dom/src/__tests__/ReactDOMFiber-test.js index fefcb2b08008d..36c8367af5d48 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFiber-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFiber-test.js @@ -1154,9 +1154,15 @@ describe('ReactDOMFiber', () => { expect(ops).toEqual(['A']); if (__DEV__) { - // TODO: this warning shouldn't be firing in the first place if user didn't call it. const errorCalls = console.error.calls.count(); - for (let i = 0; i < errorCalls; i++) { + expect(console.error.calls.argsFor(0)[0]).toMatch( + 'ReactDOM.render is no longer supported in React 18', + ); + expect(console.error.calls.argsFor(1)[0]).toMatch( + 'ReactDOM.render is no longer supported in React 18', + ); + // TODO: this warning shouldn't be firing in the first place if user didn't call it. + for (let i = 2; i < errorCalls; i++) { expect(console.error.calls.argsFor(i)[0]).toMatch( 'unstable_flushDiscreteUpdates: Cannot flush updates when React is already rendering.', ); diff --git a/packages/react-dom/src/__tests__/ReactErrorBoundaries-test.internal.js b/packages/react-dom/src/__tests__/ReactErrorBoundaries-test.internal.js index 02e4833685528..85c7a2311e0c2 100644 --- a/packages/react-dom/src/__tests__/ReactErrorBoundaries-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactErrorBoundaries-test.internal.js @@ -787,16 +787,22 @@ describe('ReactErrorBoundaries', () => { it('logs a single error when using error boundary', () => { const container = document.createElement('div'); - expect(() => - ReactDOM.render( - - - , - container, - ), - ).toErrorDev('The above error occurred in the component:', { - logAllErrors: true, - }); + spyOnDev(console, 'error'); + ReactDOM.render( + + + , + container, + ); + if (__DEV__) { + expect(console.error).toHaveBeenCalledTimes(2); + expect(console.error.calls.argsFor(0)[0]).toContain( + 'ReactDOM.render is no longer supported', + ); + expect(console.error.calls.argsFor(1)[0]).toContain( + 'The above error occurred in the component:', + ); + } expect(container.firstChild.textContent).toBe('Caught an error: Hello.'); expect(Scheduler).toHaveYielded([ diff --git a/packages/react-dom/src/__tests__/ReactErrorLoggingRecovery-test.js b/packages/react-dom/src/__tests__/ReactErrorLoggingRecovery-test.js index 21b868557ef2c..616bb1ba2a66f 100644 --- a/packages/react-dom/src/__tests__/ReactErrorLoggingRecovery-test.js +++ b/packages/react-dom/src/__tests__/ReactErrorLoggingRecovery-test.js @@ -43,6 +43,13 @@ describe('ReactErrorLoggingRecovery', () => { beforeEach(() => { console.error = error => { + if ( + typeof error === 'string' && + error.includes('ReactDOM.render is no longer supported in React 18') + ) { + // Ignore legacy root deprecation warning + return; + } throw new Error('Buggy console.error'); }; }); diff --git a/packages/react-dom/src/__tests__/ReactLegacyErrorBoundaries-test.internal.js b/packages/react-dom/src/__tests__/ReactLegacyErrorBoundaries-test.internal.js index b661ead42df3f..92de8b413b163 100644 --- a/packages/react-dom/src/__tests__/ReactLegacyErrorBoundaries-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactLegacyErrorBoundaries-test.internal.js @@ -668,16 +668,22 @@ describe('ReactLegacyErrorBoundaries', () => { it('logs a single error using both error boundaries', () => { const container = document.createElement('div'); - expect(() => - ReactDOM.render( - - - , - container, - ), - ).toErrorDev('The above error occurred in the component', { - logAllErrors: true, - }); + spyOnDev(console, 'error'); + ReactDOM.render( + + + , + container, + ); + if (__DEV__) { + expect(console.error).toHaveBeenCalledTimes(2); + expect(console.error.calls.argsFor(0)[0]).toContain( + 'ReactDOM.render is no longer supported', + ); + expect(console.error.calls.argsFor(1)[0]).toContain( + 'The above error occurred in the component:', + ); + } expect(container.firstChild.textContent).toBe('Caught an error: Hello.'); expect(log).toEqual([ diff --git a/packages/react-dom/src/__tests__/ReactLegacyRootWarnings-test.js b/packages/react-dom/src/__tests__/ReactLegacyRootWarnings-test.js new file mode 100644 index 0000000000000..f8d039124f4e2 --- /dev/null +++ b/packages/react-dom/src/__tests__/ReactLegacyRootWarnings-test.js @@ -0,0 +1,38 @@ +let ReactDOM = require('react-dom'); + +describe('ReactDOMRoot', () => { + let container; + + beforeEach(() => { + jest.resetModules(); + container = document.createElement('div'); + ReactDOM = require('react-dom'); + }); + + test('deprecation warning for ReactDOM.render', () => { + spyOnDev(console, 'error'); + + ReactDOM.render('Hi', container); + expect(container.textContent).toEqual('Hi'); + if (__DEV__) { + expect(console.error).toHaveBeenCalledTimes(1); + expect(console.error.calls.argsFor(0)[0]).toContain( + 'ReactDOM.render is no longer supported', + ); + } + }); + + test('deprecation warning for ReactDOM.hydrate', () => { + spyOnDev(console, 'error'); + + container.innerHTML = 'Hi'; + ReactDOM.hydrate('Hi', container); + expect(container.textContent).toEqual('Hi'); + if (__DEV__) { + expect(console.error).toHaveBeenCalledTimes(1); + expect(console.error.calls.argsFor(0)[0]).toContain( + 'ReactDOM.hydrate is no longer supported', + ); + } + }); +}); diff --git a/packages/react-dom/src/client/ReactDOMLegacy.js b/packages/react-dom/src/client/ReactDOMLegacy.js index f1ee572ee6eff..e85a5541b19e6 100644 --- a/packages/react-dom/src/client/ReactDOMLegacy.js +++ b/packages/react-dom/src/client/ReactDOMLegacy.js @@ -219,6 +219,15 @@ export function hydrate( container: Container, callback: ?Function, ) { + if (__DEV__) { + console.error( + 'ReactDOM.hydrate is no longer supported in React 18. Use createRoot ' + + 'instead. Until you switch to the new API, your app will behave as ' + + "if it's running React 17. Learn " + + 'more: https://reactjs.org/link/switch-to-createroot', + ); + } + invariant( isValidContainer(container), 'Target container is not a DOM element.', @@ -250,6 +259,15 @@ export function render( container: Container, callback: ?Function, ) { + if (__DEV__) { + console.error( + 'ReactDOM.render is no longer supported in React 18. Use createRoot ' + + 'instead. Until you switch to the new API, your app will behave as ' + + "if it's running React 17. Learn " + + 'more: https://reactjs.org/link/switch-to-createroot', + ); + } + invariant( isValidContainer(container), 'Target container is not a DOM element.', diff --git a/scripts/jest/shouldIgnoreConsoleError.js b/scripts/jest/shouldIgnoreConsoleError.js index cae46ac7c8c32..7534b4339abbf 100644 --- a/scripts/jest/shouldIgnoreConsoleError.js +++ b/scripts/jest/shouldIgnoreConsoleError.js @@ -13,6 +13,16 @@ module.exports = function shouldIgnoreConsoleError(format, args) { // Ignore it too. return true; } + if ( + format.indexOf('ReactDOM.render is no longer supported in React 18') !== + -1 || + format.indexOf( + 'ReactDOM.hydrate is no longer supported in React 18' + ) !== -1 + ) { + // We haven't finished migrating our tests to use createRoot. + return true; + } } } else { if (