Skip to content
This repository has been archived by the owner on Feb 14, 2023. It is now read-only.

Can't call forceUpdate on a component that is not yet mounted #55

Closed
EskelCz opened this issue Apr 3, 2019 · 7 comments
Closed

Can't call forceUpdate on a component that is not yet mounted #55

EskelCz opened this issue Apr 3, 2019 · 7 comments
Assignees
Labels
support A user is requesting support.

Comments

@EskelCz
Copy link

EskelCz commented Apr 3, 2019

Hi. Thanks for the library, I love the concept and ease of use.

I have probably an uncommon use case. I have in the dom tree a wrapper component to handle adding and removing of toast notifications. It works when I use context provider and consumers, but I want to be able to call the method for adding a toast with a single static method call from literary anywhere, without consumer wrappers, from all classes and functions, be it react component of not.

So I figured out I can extract the adding function to a static single instance class (ToastAPI) and have it share state (list of toasts) with the wrapper component using your global state. But when called, I'm getting the error in the title for some reason. :(

My question is, is there some check that prohibits me from calling setGlobal from an unmounted react component or any class/function outside of react?

Thanks. Hopefully I've explained it clear enough. I can elaborate if need be.

@quisido
Copy link
Collaborator

quisido commented Apr 3, 2019

Can you provide a minimal implementation of this so that I can be sure I understand what is happening in your use case?

@quisido quisido self-assigned this Apr 3, 2019
@quisido quisido added the support A user is requesting support. label Apr 3, 2019
@EskelCz
Copy link
Author

EskelCz commented Apr 4, 2019

Strange thing, I've made the minimal implementation with basically the same code and it's working.
https://snack.expo.io/@eskel/globaltoasts

I guess it's not a reactn issue then, sorry.

@EskelCz EskelCz closed this as completed Apr 4, 2019
@EskelCz
Copy link
Author

EskelCz commented Apr 5, 2019

@CharlesStover I've examined it a little more and it seems that the origin is indeed in reactn, the enqueueForceUpdate call. I guess snack has a different YellowBox settings or their forked RN behaves differently. I see it in React Native 0.59.2. Here is a screenshot of the warning:

screenshot of warning

So the question is, do you support calls from unmounted components?

@EskelCz EskelCz reopened this Apr 5, 2019
@quisido
Copy link
Collaborator

quisido commented Apr 6, 2019

I would like to support your use case where possible. Can you provide a minimal implementation that causes this error? You mentioned the code sandbox provided above works.

@EskelCz
Copy link
Author

EskelCz commented Apr 6, 2019

@CharlesStover I found out that the sandbox (Expo snack) has it's own implementation of console and is not showing all React Native warnings. :( I'll let them now.

The code works both in sandbox and in production code, it's just the warning that forceUpdate should not be run in my case.

I've made and tested the minimal implementation, (it shows the warning) but it takes some time to build and install, if you don't have much experience with RN.
Here: https://github.com/EskelCz/reactn-global-test/blob/master/App.js

@quisido
Copy link
Collaborator

quisido commented Apr 6, 2019

Thank you for the example. Why are you extending Component if it's not a React Component? If it's just for the global member variables and methods, you can import those directly from reactn, the same way you instantiated the state.

class ToastAPI extends Component {
  showToast (text) {
    const toastList = this.global.toasts
    toastList.push({ text: 'Some toast' })
    this.setGlobal({ toasts: toastList })
  }
}
export const Toasts = new ToastAPI()

can be:

import { setGlobal } from 'reactn';
export function showToast(text) {
  setGlobal(global => ({
    toasts: global.toasts.concat([ { text: 'Some toast' } ]),
  });
};

If you want to maintain your toast API as a class, just don't extend Component:

import { setGlobal } from 'reactn';
class ToastAPI {
  showToast(text) {
    setGlobal(global => ({
      toasts: global.toasts.concat([ { text: 'Some toast' } ]),
    });
  }
};
export const Toasts = new ToastAPI();

Does this solve your problem while meeting your use case? My interpretation of the problem is that you were wanting ReactN's global state functionality outside of a React Component.

@EskelCz
Copy link
Author

EskelCz commented Apr 6, 2019

Awesome, that did it. :) At first I was using vanilla class but then I didn't know how to get the global state inside it. I must admit I don't really find the callback pattern very readable setGlobal(global => ({. But it works and doesn't cause the warning. Thanks a lot!

@EskelCz EskelCz closed this as completed Apr 6, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
support A user is requesting support.
Projects
None yet
Development

No branches or pull requests

2 participants