React Testing Library Warning: Can't perform a React state update on an unmounted component

Viewed 1010

I am getting an error when running my code coverage tests using React Testing Library. I believe I am getting the error because my tests are unmounting before the state update is triggered in my component.

  const {
    personSuccessAlert,
    setPersonSuccessAlert,
    updatePersonSuccessAlert,
    setUpdatePersonSuccessAlert,
  } = useContext(PeopleContext);

  useEffect(() => {
    setTimeout(() => {
      setPersonSuccessAlert(false);
      setUpdatePersonSuccessAlert(false);
    }, 3000);
  }, [peopleData, updatePersonSuccessAlert]);

My useEffect has a 3 second timeout before calling two functions will will update the state in context.

import React, { createContext, useState } from 'react';

export const PeopleContext = createContext();

const PeopleContextProvider = ({
  children,
  initialPersonSuccessAlert = false,
  initialEditSuccessAlert = false,
}) => {
  const [personSuccessAlert, setPersonSuccessAlert] = useState(
    initialPersonSuccessAlert,
  );
  const [updatePersonSuccessAlert, setUpdatePersonSuccessAlert] = useState(
    initialEditSuccessAlert,
  );

  return (
    <PeopleContext.Provider
      value={{
        personSuccessAlert,
        updatePersonSuccessAlert,
        setPersonSuccessAlert,
        setUpdatePersonSuccessAlert,
      }}>
      {children}
    </PeopleContext.Provider>
  );
};

export default PeopleContextProvider;

I am trying to figure out how to either mock the two functions or keep my test mounted long enough for the state update.

Here is what I am trying

  test('onClick of person name to route to person record view loading for person record', async () => {
    const history = createMemoryHistory();
    history.push('/people');
    const providerProps = { personSuccessAlert: true };
    const { getByText } = render(
      <MockedProvider mocks={getPeople} addTypename={false}>
        <PeopleContextProvider {...providerProps}>
          <Router history={history}>
            <Switch>
              <Route exact path="/people" component={People} />
              <Route path="/people/:id" component={PersonRecord} />
            </Switch>
          </Router>
        </PeopleContextProvider>
      </MockedProvider>,
    );
    expect(getByText('Loading')).toBeInTheDocument();  
    await act(async () => new Promise((resolve) => setTimeout(resolve, 3500)));
  });

I have tried setting const setPersonSuccessAlert = jest.fn(); but haven't found success with that.

Any ideas how to keep my component mounted?

0 Answers
Related