question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

render component that set state inside of useEffect at component mount.

See original GitHub issue

Hey, I am trying to test a component that has useEffect and I am setting a state inside of it.

everytime tun the following test

import React from 'react';
import { render } from 'react-native-testing-library';

import { Home } from '../Home';
import { MockedProvider } from '../../core/utils/tests/mockedProvider';

describe('<Home />', () => {
  const { toJSON } = render(
    <MockedProvider>
      <Home />
    </MockedProvider>
  );

  it('should match <HomeScreen /> snapshot', () => {
    expect(toJSON()).toMatchSnapshot();
  });
});

I got the following error

  console.error node_modules/react-test-renderer/cjs/react-test-renderer.development.js:104
    Warning: An update to HomeScreen 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://fb.me/react-wrap-tests-with-act

however, my test passes and works well. I have searched for a solution for this and did as the error message suggested and wrapped my render method inside of act like the following

import React from 'react';
import { act, render } from 'react-native-testing-library';

import { Home } from '../Home';
import { MockedProvider } from '../../core/utils/tests/mockedProvider';

describe('<Home />', () => {
  it('should match <HomeScreen /> snapshot', async () => {
    let renderedComponent;
    await act(async () => {
      renderedComponent = render(
        <MockedProvider>
          <Home />
        </MockedProvider>
      );
    });
    expect(renderedComponent.toJSON()).toMatchSnapshot();
  });
});

and I ended up with the following error

Error: Can't access .root on unmounted test renderer

at Object.get [as root] (/Users/MuhmdRaouf/mobile-project/node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15901:17)
at render (/Users/MuhmdRaouf/mobile-project/node_modules/react-native-testing-library/build/render.js:1:1517)
at _callee$ (/Users/MuhmdRaouf/mobile-project/src/screens/__tests__/Home-test.js:12:27)
at tryCatch (/Users/MuhmdRaouf/mobile-project/node_modules/regenerator-runtime/runtime.js:45:40)
at Generator.invoke [as _invoke] (/Users/MuhmdRaouf/mobile-project/node_modules/regenerator-runtime/runtime.js:271:22)
at Generator.prototype.<computed> [as next] (/Users/MuhmdRaouf/mobile-project/node_modules/regenerator-runtime/runtime.js:97:21)
  at tryCatch (/Users/MuhmdRaouf/mobile-project/node_modules/regenerator-runtime/runtime.js:45:40)
  at invoke (/Users/MuhmdRaouf/mobile-project/node_modules/regenerator-runtime/runtime.js:135:20)
  at /Users/MuhmdRaouf/mobile-project/node_modules/regenerator-runtime/runtime.js:170:11
  at tryCallTwo (/Users/MuhmdRaouf/mobile-project/node_modules/promise/lib/core.js:45:5)

is there a way to fix this problem, I know it’s harmless for the time being but I wanna know the reason behind it as if I faced the same problem in the future I could be able to overcome it easily.

Thanks in Advance 😄

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:3
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
thymikeecommented, Feb 25, 2020
1reaction
LydGol90commented, Mar 16, 2020

This works for me. I update the state inside useEffect on mount.

  it('should...', async () => {
    const { queryByType } = render(<Screen />);
    await act(async () => flushMicrotasksQueue());
    expect(...)
  });
Read more comments on GitHub >

github_iconTop Results From Across the Web

Using the Effect Hook - React
Placing useEffect inside the component lets us access the count state variable (or any props) right from the effect. We don't need a...
Read more >
Can I set state inside a useEffect hook - Stack Overflow
Generally speaking, using setState inside useEffect will create an infinite loop that most likely you don't want to cause.
Read more >
How the useEffect Hook Works (with Examples) - Dave Ceddia
It's the solution to many problems: how to fetch data when a component mounts, how to run code when state changes or when...
Read more >
The last guide to the useEffect Hook you'll ever need
The first two log outputs are due to the initial rendering after the component was mounted. Let's add another state variable to the...
Read more >
React hooks gotchas: setState in async useEffect
Using this approach, the <App /> component will render 4 times: Render 1: initial mount; Render 2: setPending(true) in the useEffect() causes the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found