Skip to content

Receiving 'event was not wrapped in act' warning after upgrading to React 18 #1216

Open
@atshakil

Description

@atshakil
  • @testing-library/react version: 14.0.0
  • Testing Framework and version: jest
  • DOM Environment:

Relevant code or config:

// CompA.tsx

const CompA = () => null;
export default CompA;

// CompB.tsx

import { lazy } from "react";

const CompB = () => {
  const Example = lazy(() => import("./CompA"));

  return <Example />;
};

export default CompB;

// CompC.tsx

import CompB from './CompB';

const CompC = () => <CompB />;

export default CompC;

// CompC.test.tsx

import { render } from "@testing-library/react";
import CompC from './CompC';

// This test will throw `act()` warning even though CompC is not using `lazy` directly.
describe("CompC", () => {
  test(`Renders`, () => {
    expect(() => {
      render(<CompC />);
    }).not.toThrow();
  });
});

What you did:

Run test using yarn test from a CRA configured project.

What happened:

Receiving warning,

console.error
    Warning: A suspended resource finished loading inside a test, but the event was not wrapped in act(...).
    
    When testing, code that resolves suspended data should be wrapped into act(...):
    
    act(() => {
      /* finish loading suspended data */
    });
    /* assert on the output */
    
    This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act

Reproduction:

Sandbox: https://codesandbox.io/p/sandbox/demo-act-warning-nested-1p4vjn?selection=%5B%7B%22endColumn%22%3A1%2C%22endLineNumber%22%3A1%2C%22startColumn%22%3A1%2C%22startLineNumber%22%3A1%7D%5D&file=%2Fsrc%2FCompC.test.tsx%3A7%2C25

Problem description:

act() warning started to appear after upgrading to React 18.

Wrapping with waitFor approach (as suggested here) has the following drawback.

Considering lazy is used on a shared component, we'll have to update all the tests for all the components that are using the shared component (even though those components are not using lazy directly). For a large codebase, we'll have to update tests for hundreds of components. Even if we have only one shared component using lazy, we'll have to update all the dependent component tests.

Seems like a lot of work!

Could we somehow keep the behavior identical to that on React 16 (act warning is not raised without needing waitFor)? It'll save a lot of developer effort.

Suggested solution:

No warning message

Activity

alone548

alone548 commented on May 31, 2023

@alone548

can i work on this.

alexandrsashin

alexandrsashin commented on May 31, 2023

@alexandrsashin

@kentcdodds @eps1lon
The problem is in new concurrent rendering in React 18, right?
Do we plan to fix such issue in the next major version?

MatanBobi

MatanBobi commented on Jun 1, 2023

@MatanBobi
Member

@alexandrsashin The current version of RTL already supports React 18. Having said that, we do have some work that @eps1lon has been working on in our alpha version, @atshakil, can you please upgrade to our alpha version to see if this resolves your issue? :)

Thanks.

atshakil

atshakil commented on Jun 6, 2023

@atshakil
Author

@MatanBobi I tested using the PR build from @eps1lon.
And, it works without any warning! Great!

"@testing-library/react": "https://pkg.csb.dev/testing-library/react-testing-library/commit/b156f877/@testing-library/react"

Looking forward to a release soon! :)

alexandrsashin

alexandrsashin commented on Jun 16, 2023

@alexandrsashin

@atshakil then you can close such issue.)

MatanBobi

MatanBobi commented on Jun 16, 2023

@MatanBobi
Member

Let's keep this one open until alpha will be merged to main :)

linked a pull request that will close this issuefix: Require `await act(...)` #1214on Jun 17, 2023
eps1lon

eps1lon commented on Jun 17, 2023

@eps1lon
Member

Yeah this is one of the scenarios we'd like to address with #1214 but it needs some additional time.

If you're blocked by this, you can always render().unmount() or cleaup() before you exit your test e.g.

+import {cleanup} from '@testing-library/react';

 expect(() => {
   render(<CompC />);
 }).not.toThrow();
+cleanup()
TAGC

TAGC commented on Jul 25, 2023

@TAGC

I think I've encountered something similar to this. I've been working on upgrading one of our frontend projects to React 18 and I was a bit stumped seeing thousands of warning messages like the following when running the unit tests after upgrading the React and React Testing Library packages:

console.error
    Warning: An update to Temp inside a test was not wrapped in act(...).

    When testing, code that causes React state updates should be wrapped into act(...):

    act(() => {
      /* fire events that update state */
    });
    /* assert on the output */

    This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act
        at Temp (/Users/.../src/components/Temp/Temp.tsx:5:23)

       6 |   return (
       7 |     <div>
    >  8 |       <button role="button" onClick={() => setFoo(true)}>
         |                                            ^
       9 |         Example
      10 |       </button>
      11 |     </div>

      at printWarning (node_modules/react-dom/cjs/react-dom.development.js:86:30)
      at error (node_modules/react-dom/cjs/react-dom.development.js:60:7)
      at warnIfUpdatesNotWrappedWithActDEV (node_modules/react-dom/cjs/react-dom.development.js:27589:9)
      at scheduleUpdateOnFiber (node_modules/react-dom/cjs/react-dom.development.js:25508:5)
      at setFoo (node_modules/react-dom/cjs/react-dom.development.js:17527:7)
      at onClick (src/components/Temp/Temp.tsx:8:44)
      at HTMLUnknownElement.callCallback (node_modules/react-dom/cjs/react-dom.development.js:4164:14)

 PASS  src/components/Temp/Temp.spec.tsx
  Temp
    ✓ foo (75 ms)

Our company has a very similar frontend project that made the jump to React 18 several months back and doesn't have this issue, so I was puzzled what the difference was.

I've finally been able to narrow it down to what appears to be a regression between v13.4.0 and v14.0.0 of this package - or more specifically, between v13.5.0-alpha.1 (which is okay) and v14.0.0-alpha.1. With v13.5.0-alpha.1 or earlier, the output when running the same test is simply:

 PASS  src/components/Temp/Temp.spec.tsx
  Temp
    ✓ foo (49 ms)

This was the component I was testing:

import { useState } from 'react'

export function Temp() {
  const [_, setFoo] = useState(false)

  return (
    <div>
      <button role="button" onClick={() => setFoo(true)}>
        Example
      </button>
    </div>
  )
}

This was my test case:

import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'

import { Temp } from './Temp'

describe('Temp', () => {
  it('foo', async () => {
    render(<Temp />)

    await userEvent.click(screen.getByRole('button', { name: 'Example' }))
  })
})
alexandrsashin

alexandrsashin commented on Jul 25, 2023

@alexandrsashin

@TAGC Yes, versions of libraries are important. When I had problems with act(...) warnings I analyzed schema of RTL dependencies and carefully upgraded all of them.
https://twitter.com/AlexandrSashin/status/1670814494119821312/photo/1
It solved my problems.

Your test looks good and you can improve it using userEvent.setup(). As I understood from docs (https://testing-library.com/docs/user-event/setup/) using userEvent.setup() is recommended in v14 and further versions userEvent-library.

25 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @dougludlow@runoncedev@TAGC@michalstrzelecki@btmnk

      Issue actions

        Receiving 'event was not wrapped in act' warning after upgrading to React 18 · Issue #1216 · testing-library/react-testing-library