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

setState() on unmounted component, possible bug or misunderstanding? #180

Closed
linkenneth opened this issue Dec 11, 2018 · 3 comments
Closed
Labels

Comments

@linkenneth
Copy link

Hi! Thanks again for the great library.

I upgraded from loadable-components@2.2.3 to @loadable/component@5.2.1 in order to use the now-supported refs of #108, but after some tweaking I'm still stuck with the following error:

Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
    in InnerLoadable (created by Context.Consumer)
    in Unknown (created by ForwardRef)

The complaint seems to be that loadAsync(), triggered from componentDidMount() https://github.com/smooth-code/loadable-components/blob/4e99a97c5ae958c4f18ac82b7e1a3566bc81c912/packages/component/src/createLoadable.js#L63 seems to be somehow calling this.setState https://github.com/smooth-code/loadable-components/blob/4e99a97c5ae958c4f18ac82b7e1a3566bc81c912/packages/component/src/createLoadable.js#L96 despite not being mounted. That is, the InnerLoadable component itself is not yet mounted, despite being called from componentDidMount. Is this ever possible?

It's a bit hard to share the entirety of my own code, as it's our entry point that triggers the error. For what it's worth, this is the component causing the problem:

import React from 'react';
import ReactDOM from 'react-dom';
import loadable from '@loadable/component';

import { Dimmer, Loader } from 'semantic-ui-react';

const LoadingView = () => (
  <Dimmer active>
    <Loader>课程加载中...</Loader>
  </Dimmer>
);

const AsyncLessonView = loadable(() => import('./LessonView.jsx'), {
  fallback: <LoadingView />
});

export default AsyncLessonView;

const main = document.getElementById('main');
if (main) {
  ReactDOM.render(<AsyncLessonView />, main);
}

If it helps as well, there may also be a few other loadables loaded once LessonView loads. Could that be the cause of the issue?

@linkenneth
Copy link
Author

Full stack trace of error (though I doubt it helps because webpack):

  | warningWithoutStack | @ | react-dom.development.js:512
-- | -- | -- | --
  | warnAboutUpdateOnUnmounted | @ | react-dom.development.js:15630
  | scheduleWork | @ | react-dom.development.js:16927
  | enqueueSetState | @ | react-dom.development.js:11623
  | Component.setState | @ | react.development.js:413
  | (anonymous) | @ | loadable.es.js:195
  | Promise.then (async) |   |  
  | loadAsync | @ | loadable.es.js:194
  | componentDidMount | @ | loadable.es.js:160
  | commitLifeCycles | @ | react-dom.development.js:14685
  | commitAllLifeCycles | @ | react-dom.development.js:15905
  | callCallback | @ | react-dom.development.js:145
  | invokeGuardedCallbackDev | @ | react-dom.development.js:195
  | invokeGuardedCallback | @ | react-dom.development.js:248
  | commitRoot | @ | react-dom.development.js:16075
  | completeRoot | @ | react-dom.development.js:17463
  | performWorkOnRoot | @ | react-dom.development.js:17391
  | performWork | @ | react-dom.development.js:17295
  | performSyncWork | @ | react-dom.development.js:17267
  | requestWork | @ | react-dom.development.js:17155
  | scheduleWork | @ | react-dom.development.js:16949
  | scheduleRootUpdate | @ | react-dom.development.js:17637
  | updateContainerAtExpirationTime | @ | react-dom.development.js:17664
  | updateContainer | @ | react-dom.development.js:17691
  | ReactRoot.render | @ | react-dom.development.js:17957
  | (anonymous) | @ | react-dom.development.js:18097
  | unbatchedUpdates | @ | react-dom.development.js:17518
  | legacyRenderSubtreeIntoContainer | @ | react-dom.development.js:18093
  | render | @ | react-dom.development.js:18152
  | (anonymous) | @ | AsyncLessonView.jsx:32
  | ./client/views/lessons/AsyncLessonView.jsx | @ | AsyncLessonView.bundle.js:22
  | __webpack_require__ | @ | runtime.bundle.js:89
  | checkDeferredModules | @ | runtime.bundle.js:46
  | webpackJsonpCallback | @ | runtime.bundle.js:33
  | (anonymous) | @ | AsyncLessonView.bundle.js:1

@gregberge
Copy link
Owner

Hello @linkenneth, I don't know exactly what happen in your case. But you pointed out a problem in the current implementation. The loadAsync is asynchronous and the component could be unmounted when the setState is called. I have to fix that.

@linkenneth
Copy link
Author

Thanks. I thought something was strange as well, but it doesn't look like my case is related. I also left a comment on your commit.

fivethreeo pushed a commit to fivethreeo/loadable-components that referenced this issue Nov 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants