mobx-react-lite component wrapped in `observer` renders twice in latest Next.js
dmitrytavern opened this issue · comments
Intended outcome:
Render a component wrapped in observer
once.
Actual outcome:
Component wrapped in observer
made two renders.
How to reproduce the issue:
Repro:
- Next.js v14 with bug (mobx-react-lite@4.0.5): https://codesandbox.io/p/devbox/mobx-react-lite-render-twice-q2qpk5
- Next.js v14 without bug (mobx-react-lite@3.4.3): https://codesandbox.io/p/devbox/mobx-react-lite-render-once-vjzpw9
- Create next application
- Install latest
mobx
andmobx-react-lite
- Set
reactStrictMode: false
in next.config.js - Add Child component to Index page
import { enableStaticRendering, observer } from "mobx-react-lite";
enableStaticRendering(typeof window === "undefined");
const ChildObserver = observer(function Child() {
console.log("Hello world");
return <div>Test</div>;
});
export default function Index() {
return <ChildObserver />;
}
Result:
If downgrade mobx-react-lite
to 3.4.3
:
I also tried to reproduce this bug with a pure react application, but everything works fine there (with 4.0.5 and 3.4.3 versions).
If build and run the application, the bug remains.
Versions
next@14.1.0
mobx-react-lite@4.0.5
This is because getSnapshot()
!== getServerSnapshot()
on initial render, it can be probably fixed simply by changing
https://github.com/mobxjs/mobx/blob/58d432837dbd49acf3d73ed2609967358d423702/packages/mobx-react-lite/src/useObserver.ts#L101C9-L101C26
to adm.getSnapshot
@urugator you are right, I replaced getServerSnapshot
with adm.getSnapshot
and the double rendering didn't happen. Should I create a PR with getServerSnapshot
replaced?
Yes, PR is welcome, thank you. Don't forget to provide changeset via yarn changeset
. Dunno if there is an easy way to write a unit test for this.