{
- setup(_ref);
- return cleanUp;
- }}
- />,
- container,
- );
+ await act(() => {
+ root.render(
+
{
+ setup(_ref);
+ return cleanUp;
+ }}
+ />,
+ );
+ });
expect(setup).toHaveBeenCalledTimes(2);
expect(cleanUp).toHaveBeenCalledTimes(1);
});
- it('handles ref functions with stable identity', () => {
+ it('handles ref functions with stable identity', async () => {
const container = document.createElement('div');
const cleanUp = jest.fn();
const setup = jest.fn();
@@ -645,50 +733,38 @@ describe('refs return clean up function', () => {
return cleanUp;
}
- ReactDOM.render(
, container);
+ const root = ReactDOMClient.createRoot(container);
+ await act(() => {
+ root.render(
);
+ });
expect(setup).toHaveBeenCalledTimes(1);
expect(cleanUp).toHaveBeenCalledTimes(0);
- ReactDOM.render(
-
,
- container,
- );
+ await act(() => {
+ root.render(
);
+ });
expect(setup).toHaveBeenCalledTimes(1);
expect(cleanUp).toHaveBeenCalledTimes(0);
- ReactDOM.render(
, container);
+ await act(() => {
+ root.render(
);
+ });
expect(setup).toHaveBeenCalledTimes(1);
expect(cleanUp).toHaveBeenCalledTimes(1);
});
- it('warns if clean up function is returned when called with null', () => {
+ it('warns if clean up function is returned when called with null', async () => {
const container = document.createElement('div');
const cleanUp = jest.fn();
const setup = jest.fn();
let returnCleanUp = false;
- ReactDOM.render(
-
{
- setup(_ref);
- if (returnCleanUp) {
- return cleanUp;
- }
- }}
- />,
- container,
- );
-
- expect(setup).toHaveBeenCalledTimes(1);
- expect(cleanUp).toHaveBeenCalledTimes(0);
-
- returnCleanUp = true;
-
- expect(() => {
- ReactDOM.render(
+ const root = ReactDOMClient.createRoot(container);
+ await act(() => {
+ root.render(
{
setup(_ref);
@@ -697,8 +773,27 @@ describe('refs return clean up function', () => {
}
}}
/>,
- container,
);
+ });
+
+ expect(setup).toHaveBeenCalledTimes(1);
+ expect(cleanUp).toHaveBeenCalledTimes(0);
+
+ returnCleanUp = true;
+
+ await expect(async () => {
+ await act(() => {
+ root.render(
+
{
+ setup(_ref);
+ if (returnCleanUp) {
+ return cleanUp;
+ }
+ }}
+ />,
+ );
+ });
}).toErrorDev('Unexpected return value from a callback ref in div');
});
});
diff --git a/packages/react-dom/src/__tests__/refsLegacy-test.js b/packages/react-dom/src/__tests__/refsLegacy-test.js
new file mode 100644
index 0000000000000..c3af817892ffa
--- /dev/null
+++ b/packages/react-dom/src/__tests__/refsLegacy-test.js
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @emails react-core
+ */
+
+'use strict';
+
+let React = require('react');
+let ReactDOM = require('react-dom');
+
+describe('root level refs with legacy APIs', () => {
+ beforeEach(() => {
+ jest.resetModules();
+ React = require('react');
+ ReactDOM = require('react-dom');
+ });
+
+ it('attaches and detaches root refs', () => {
+ let inst = null;
+
+ // host node
+ let ref = jest.fn(value => (inst = value));
+ const container = document.createElement('div');
+ let result = ReactDOM.render(
, container);
+ expect(ref).toHaveBeenCalledTimes(1);
+ expect(ref.mock.calls[0][0]).toBeInstanceOf(HTMLDivElement);
+ expect(result).toBe(ref.mock.calls[0][0]);
+ ReactDOM.unmountComponentAtNode(container);
+ expect(ref).toHaveBeenCalledTimes(2);
+ expect(ref.mock.calls[1][0]).toBe(null);
+
+ // composite
+ class Comp extends React.Component {
+ method() {
+ return true;
+ }
+ render() {
+ return
Comp
;
+ }
+ }
+
+ inst = null;
+ ref = jest.fn(value => (inst = value));
+ result = ReactDOM.render(
, container);
+
+ expect(ref).toHaveBeenCalledTimes(1);
+ expect(inst).toBeInstanceOf(Comp);
+ expect(result).toBe(inst);
+
+ // ensure we have the correct instance
+ expect(result.method()).toBe(true);
+ expect(inst.method()).toBe(true);
+
+ ReactDOM.unmountComponentAtNode(container);
+ expect(ref).toHaveBeenCalledTimes(2);
+ expect(ref.mock.calls[1][0]).toBe(null);
+
+ // fragment
+ inst = null;
+ ref = jest.fn(value => (inst = value));
+ let divInst = null;
+ const ref2 = jest.fn(value => (divInst = value));
+ result = ReactDOM.render(
+ [
+
,
+ 5,
+
+ Hello
+
,
+ ],
+ container,
+ );
+
+ // first call should be `Comp`
+ expect(ref).toHaveBeenCalledTimes(1);
+ expect(ref.mock.calls[0][0]).toBeInstanceOf(Comp);
+ expect(result).toBe(ref.mock.calls[0][0]);
+
+ expect(ref2).toHaveBeenCalledTimes(1);
+ expect(divInst).toBeInstanceOf(HTMLDivElement);
+ expect(result).not.toBe(divInst);
+
+ ReactDOM.unmountComponentAtNode(container);
+ expect(ref).toHaveBeenCalledTimes(2);
+ expect(ref.mock.calls[1][0]).toBe(null);
+ expect(ref2).toHaveBeenCalledTimes(2);
+ expect(ref2.mock.calls[1][0]).toBe(null);
+
+ // null
+ result = ReactDOM.render(null, container);
+ expect(result).toBe(null);
+
+ // primitives
+ result = ReactDOM.render(5, container);
+ expect(result).toBeInstanceOf(Text);
+ });
+});