Skip to content
This repository has been archived by the owner on Dec 31, 2020. It is now read-only.

mobx-react stops working due to Chrome DevTools #714

Closed
pavelserbajlo opened this issue Jun 20, 2019 · 9 comments
Closed

mobx-react stops working due to Chrome DevTools #714

pavelserbajlo opened this issue Jun 20, 2019 · 9 comments

Comments

@pavelserbajlo
Copy link

This one is really weird, but bear with me for a moment.

We're experiencing a situation where mobx-react suddenly stops working when we interact with the console in Chrome DevTools. This typically happens several minutes into the app's session (typically somewhere 5-15 mins at least and it's highly inconsistent).

forcing strict with V4:

useStrict(true);

with V5, V6:

configure({ enforceActions: 'always' });

the store instance exposes an action similar to this:

@observable isOn: boolean = false;
@action toggleIsOn() {
  this.isOn = !this.isOn;
}

I'm then attaching this method to window, so that it's accessible in the console:

(window as any).debugToggleIsOn = this.toggleIsOn;

Now when I call window.debugToggleIsOn(), all typically works. When it stops working is kinda hard to believe for me:

  • you're several minutes into the session
  • you go to Chrome DevTools and open the console
  • hit the Up Arrow to retrieve the last executed command (which is the one definted above)
  • Boom!

Just hitting that up arrow key makes store changes to stop triggering the observers awaiting changes. No errors, no warnings, no obvious debuggable issue. I'm assuming that DevTools try to evaluate that command at that point, possibly calling it or breaking the action in some way. Have you ever seen anything just like this before?

Tested with mobx-react V4, V5, V6, both latest Chrome and Canary.

Any insights or ideas appreciated!

@danielkcz
Copy link
Contributor

Any chance you have accessed React Devtools? I've noticed, it causes weird behavior sometimes. Try closing devtools completely and reproducing the issue without ever opening React devtools.

For a reference: mobxjs/mobx-state-tree#1303 (might be unrelated though)

@pavelserbajlo
Copy link
Author

Ok, we were able to reproduce the issue even without touching DevTools whatsoever (after ~30 mins). I'm creating a unique store ID upon initialization to make sure it is not being duplicated. After the issue occured, I inspected React devtools and didn't find any obvious issue. The UI now only refreshes (and pulls proper data out of store) when the change is originated in the UI state (e.g. a button click). But never to changes in story anymore.

Are you aware of any debugging technique I can leverage at this point? I tried logging extensively every step of the pipeline just to see everything is being set in the store properly, but observers are simply not being updated when that happens.

@domehead100
Copy link

domehead100 commented Jul 1, 2019

Put a breakpoint in your store constructor or a debugger statement or keep a static instance variable and then in your store constructor throw if it is not undefined iand otherwise assign it to your constructed instance This is all to ensure that you only have one store instance. Your problem sounds like you have two or more.

I leverage the regular Chrome dev tools extensively and have never had the problem you describe (though we don’t use strict mode). Using the webpack define plugin, we put a largish store, multiple models, and even internal component state of tens of components on the window in dev builds only only. I haven’t been a fan of the React dev tools, since they crash so often, with our app at least, so I use the regular dev tools for all that.

You might try turning off strict mode temporarily.

You might also make your function an arrow function to help ensure “this” is what you expect it to be.

As for mobx-specific tools, there are some. You might try onBecomeObserved/onBecomeUnobserved

Good luck!

@pavelserbajlo
Copy link
Author

I can confirm only one store instance is present in the whole app. I disabled strict mode, made sure all the action methods are either @action.bound or arrow methods with @action. I'm also using mobx spy() to monitor all actions, reaction, scheduled-reactions and errors. I also made sure the whole DOM is not being re-rendered and that there's no unusual action/reaction happening prior to the issue occurrence.

When this happens, I see no error even with spy(). Actions are triggered, but no more reactions or scheduled-reactions at all.

We're talking about a more robust application with one store and about 15 models with various association to each other, reflecting the backend DB structure or necessary runtime state data that need to be observed from multiple observers.

At this point, I'm not sure if there's anything else we can do besides dropping mobx entirely and going back to redux or rewriting majority of the code to ditch classes and move to functional components and hooks (with no guarantee this will actually help the situation).

Any further ideas welcome. Thank you.

@pavelserbajlo
Copy link
Author

I have some more info regarding this. I noticed there’s a clear correlation between the number of actions invoked in one app’s session and the issue occurrence. Our app is quite heavy on number of actions we call per second (sometimes up to 40/s). If we do this, the issue occurs in minutes. When I comment these out and just use the rest of the app, it happens in matter of hours.

I wonder now — is there anything in mobx or mobx-react that cumulates or counts over time and may cause some kind of overflow or overload (even unintentional) causing the system to stop triggering reactions?

@pavelserbajlo
Copy link
Author

Some further observations from monitoring the mobx globalState.

When all looks good, globalState looks like this:
Screenshot 2019-07-03 13 57 00

When mobx fails to trigger reactions, it looks like this:
Screenshot 2019-07-03 14 02 40

Without any deeper understanding of how inBatch works in overall, this condition doesn't look right in mobx considering inBatch === 2 in the globalState:

https://github.com/mobxjs/mobx/blob/a5cb65926621266716f8d11d716bf337e60dc3c1/src/core/observable.ts#L109

Any thoughts appreciated.

@danielkcz
Copy link
Contributor

@urugator Could you possibly have a look at this? This seems to require some deeper knowledge of MobX internals.

@urugator
Copy link
Contributor

It's a year old and seems to be sort of resolved...

@lock
Copy link

lock bot commented Jun 24, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs or questions.

@lock lock bot locked as resolved and limited conversation to collaborators Jun 24, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants