Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting state on unmounted functional components should issue a warning and fail the test #2551

Open
2 of 13 tasks
ipinyagin97 opened this issue Dec 7, 2021 · 0 comments
Open
2 of 13 tasks

Comments

@ipinyagin97
Copy link

ipinyagin97 commented Dec 7, 2021

Consider this simple component, which sends an API request on mount and sets component's state to the response:

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

export const TestComponent = ({
  fetchSomethingFromAPI,
}) => {
  const [state, setState] = useState('');

  useEffect(() => {
    fetchSomethingFromAPI().then((result) => setState(result));
  }, []);

  return <div>{state}</div>;
};

If the component had unmounted by the time the request completed, the 'infamous' "Can't perform a React state update on an unmounted component" warning would have been printed to console. However, when I try to write a failing test for this case, enzyme doesn't issue a warning and considers the test to have passed.
This is my test's code:

import React from 'react';
import { mount } from 'enzyme';
import { act } from 'react-dom/test-utils';

// auxiliary class
class MockPromise {
  const thenCallbacks = [];

  then(callback) {
    this.thenCallbacks.push(callback);
    return this;
  }

  resolve(val) {
    this.thenCallbacks.forEach((callback) => callback(val));
  }
}

describe('TestComponent', () => {
  test('should not set state on unmounted component', () => {
    const promise = new MockPromise();
    const fetchSomethingFromAPI = () => promise;
    const wrapper = mount(<TestComponent fetchSomethingFromAPI={fetchSomethingFromAPI} />);
    wrapper.unmount();
    act(() => {
      promise.resolve(null);
    });
    wrapper.update();
  });
});

This problem seems to only be affecting functional components, for class components the test would fail with the "setState() can only be called on class components" error message; while the message is not the same as it would be in dev environment, at least it allows me to test my class components for this particular case.

Current behavior

Setting state on an unmounted functional component doesn't issue a warning and allows the test to pass

Expected behavior

Setting state on an unmounted functional component should issue a warning and fail the test

Your environment

API

  • shallow
  • mount
  • render

Version

library version
enzyme 3.11.0
react 16.8.3
react-dom 16.8.3
react-test-renderer
adapter (below) 1.15.5

Adapter

  • enzyme-adapter-react-16
  • enzyme-adapter-react-16.3
  • enzyme-adapter-react-16.2
  • enzyme-adapter-react-16.1
  • enzyme-adapter-react-15
  • enzyme-adapter-react-15.4
  • enzyme-adapter-react-14
  • enzyme-adapter-react-13
  • enzyme-adapter-react-helper
  • others ( )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant