mobx icon indicating copy to clipboard operation
mobx copied to clipboard

Observer() forces components to render despite no changes made to the store

Open Artkoch opened this issue 2 years ago • 5 comments

Intended outcome: Components, that are wrapped into observer() are rendering 1 time.

Actual outcome: Components, that are wrapped into observer() are rendering 2 times. Second time is redundant. You can see React Profiler showing the renders. As for the cause for the render is says "Hook 2 changed". Screenshot 2023-05-14 at 16 19 14

No changes made to the store. Is this an intended behaviour? If so, how to avoid second renders?

How to reproduce the issue: I've recreated the issue in codesandbox https://codesandbox.io/s/ecstatic-jennings-cnpp9b?file=/src/FeedItem.js

Versions mobx 6.9.0 mobx-react-lite 3.4.3 react 18.2.0

Artkoch avatar May 14 '23 13:05 Artkoch

It might be due to React strict mode enabled in your code: https://stackoverflow.com/a/61897567

In this case in production you won't get double renders.

kubk avatar May 14 '23 17:05 kubk

https://react.dev/reference/react/StrictMode#fixing-bugs-found-by-double-rendering-in-development

urugator avatar May 16 '23 08:05 urugator

Thank you for answer. Ok, so react double-renders every component so I would spot the troublesome component. My question is the following, the fact that component that is wrapped with Observer is re-rendering isn't it the sign that there is a problem with observer component. Just like it's said in React Docs. Because if there would be no issue with observer, the component in profiler would be grey and not yellow.

Alternatively, if observer wrapper is ok. Then, if you could be so kind and point me to prop or state that changing on each render and causes the observer to trigger the update

Artkoch avatar May 20 '23 16:05 Artkoch

the component in profiler would be grey and not yellow.

Not sure if I follow.

https://legacy.reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html#flame-chart The color of a bar indicates how long the component (and its children) took to render in the selected commit. Yellow components took more time, blue components took less time, and gray components did not render at all during this commit.

urugator avatar May 27 '23 11:05 urugator

I happen to have a simiular issue deep inside a react app after upgrading from [email protected] to [email protected]. I have <React.StrictMode> off.

I cannot currently isolate the problem as it happends too deep inside a large react app. Maybe not related but it does happen the moment I navigate() from react-router.

The Profiler tells for Why did this render? Hook 2 changed.

Downgrading just mobx-react from 9.1.0 to 7.6.0 removes the issue.

jrmyio avatar Dec 13 '23 15:12 jrmyio