question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Bug: MobX-like observer pattern doesn't work with Fast Refresh because Hooks don't get detected

See original GitHub issue

React version: 17.0.0

Steps To Reproduce

  1. https://codesandbox.io/s/react-refresh-webpack-plugin-rendered-more-hooks-than-during-the-previous-render-issue-ezcrz?file=/src/Comp.js
  2. Delete one of the hooks there

Link to code example: https://codesandbox.io/s/react-refresh-webpack-plugin-rendered-more-hooks-than-during-the-previous-render-issue-ezcrz?file=/src/Comp.js

The current behavior

You get “Rendered more hooks than during the previous render” error

The expected behavior

Should hot reload and re-mount the component.

The source of the issue have two parts:

  1. react-refresh and the bundler fails to inject signature to the component
  2. When no signature apparent, react-refresh consider the components as compatible, which is not always true, as in the repro https://github.com/facebook/react/blob/9aca239f11f31109dc1a229aa1571c2bf02f5524/packages/react-refresh/src/ReactFreshRuntime.js#L126-L132

I’ve filed an issue also for the webpack plugin: https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/266 Mobx related issue: https://github.com/mobxjs/mobx/issues/2668

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:4
  • Comments:73 (44 by maintainers)

github_iconTop GitHub Comments

6reactions
gaearoncommented, Mar 30, 2021

react-refresh@0.10.0 is out with the fix. I’ll file an issue against the webpack plugin to update it, but feel free to upgrade it manually to try it in your project.

6reactions
gaearoncommented, Mar 26, 2021

Let me describe the problem a bit clearer. Fast Refresh works by tagging functions with “signatures”.

// V1
function Foo() {
  useA()
}

// V2
function Foo() {
  useA()
  useB()
}

These two versions of Foo would get different “signatures”, so we’d know to remount them.

These signatures are specified through calls to a special function.

// V1
let Foo = _s(function Foo() {
  useA()  
}, 'abcde')

// V2
let Foo = _s(function Foo() {
  useA()  
  useB()  
}, 'qwerty')

The tricky part is what happens when it’s a HOC. Because the part getting signed is the inner one.

// V1
let Foo = observer(_s(function Foo() {
  useA()  
}, 'abcde'))

// V2
let Foo = observer(_s(function Foo() {
  useA()  
  useB()  
}, 'qwerty'))

This would normally work fine. React would see that the signature associated Foo is different, so all Foo components need to be remounted.

The problem with what MobX is doing is that Foo does not end up being a component in the tree. MobX just calls it as a function: Foo(). The only component React sees is the MobX generated wrapper. React has no idea that the _s call it did for Foo actually describes the signature of the wrapper that calls Foo().

React doesn’t find Foo in the tree, and it thinks that MobX wrappers are completely safe to keep mounted, since their own signatures haven’t changed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

observer from 'mobx-react-lite' not working - Stack Overflow
I finally find the problem. in new version of mobx-react-lite you need to call 'makeObservable' in 'constructor' like below:
Read more >
mobxjs/mobx - Gitter
Hi, i'm new to mobx and i already integrated it into react native app. I currently save array of objects in async storage...
Read more >
mobx-react | Yarn - Package Manager
Package with React component wrapper for combining React with MobX. Exports the observer decorator and other utilities. For documentation, see the MobX ......
Read more >
Introduction to MobX with React - LogRocket Blog
In this tutorial, we will discuss how to use MobX with React, but first, we will begin by getting to understand MobX a...
Read more >
MobX Quick Start Guide
He has been working with React since 2013 and MobX since 2016. ... Once the gang of four standardized the observer design pattern,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found