visgl / react-google-maps

React components and hooks for the Google Maps JavaScript API
https://visgl.github.io/react-google-maps/
MIT License
1k stars 65 forks source link

[Bug] Warning: useLayoutEffect does nothing on the server #381

Open adrenaline681 opened 1 month ago

adrenaline681 commented 1 month ago

Description

After installing the react-google-maps package we started getting the following error:

Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://reactjs.org/link/uselayouteffect-ssr for common fixes.
2024-05-24T18:49:02.004220106Z     at Map (file:///app/node_modules/@vis.gl/react-google-maps/dist/index.modern.mjs:805:5)

In our own project we used something like this to prevent this warning issue. const useIsomorphicLayoutEffect = typeof window === 'undefined' ? React.useEffect : React.useLayoutEffect

This means that it will use useLayoutEffect normally, but during Server Side Rendering it will use useEffect

Steps to Reproduce

Use react-google-maps inside of a NextJS project.

Environment

Logs

Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://reactjs.org/link/uselayouteffect-ssr for common fixes.
2024-05-24T18:49:02.004220106Z     at Map (file:///app/node_modules/@vis.gl/react-google-maps/dist/index.modern.mjs:805:5)
usefulthink commented 1 month ago

We certainly don't want to trigger these warnings when rendering on the server, but I'm trying to figure out what would be the best way to do that.

The suggested solution (useIsomorphicLayoutEffect()) doesn't feel like a good choice – it's just pretending not to use useLayoutEffect when in fact it will use it when it counts. This can lead to problems (not in our case since we're not modifying the DOM, more in general).

In case of our Map component which is triggering the warning, I have two thoughts:

kevinjavitz commented 4 weeks ago

Having the same issue

For a temporary fix where do I put that code?

const useIsomorphicLayoutEffect = typeof window === 'undefined' ? React.useEffect : React.useLayoutEffect All the warnings make it difficult to read the console.logs when debugging

I am using Remix so I guess it's rendering something server side

Error message:

 Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the 
initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://reactjs.org/link/uselayouteffect-ssr 
for common fixes.
10:58:14 │ remix      │     at Map (file:///home/kjavitz/Learning/routing/node_modules/@vis.gl/react-google-maps/dist/index.modern.mjs:805:5)
10:58:14 │ remix      │     at MapWrapper (/home/kjavitz/Learning/routing/app/components/mapwrapper.jsx:18:69)
10:58:14 │ remix      │     at APIProvider (file:///home/kjavitz/Learning/routing/node_modules/@vis.gl/react-google-maps/dist/index.modern.mjs:286:7)
usefulthink commented 4 weeks ago

I've seen this recommended several times, mostly related to unit-testing, but you could give this a shot: Somewhere in the code that exclusively runs on the server (no Idea how that works with remix, sorry), you could add this code that disables the useLayoutEffect hook entirely:

import React from 'react';

React.useLayoutEffect = React.useEffect;

Let me know if that works.

shuuji3 commented 4 weeks ago

For Remix, I don't have much experience with Remix either, but maybe you can use the client module setting to avoid server rendering if you haven't tried it yet.

Server vs. Client Code Execution | Remix - https://remix.run/docs/en/main/discussion/server-vs-client#splitting-up-client-and-server-code