qosenergy / shared-store-hook

Easily share state data between several React components. It's just like useState, but shared.
3 stars 2 forks source link

Make compatible with Serverside rendering #7

Open Diabl0570 opened 1 year ago

Diabl0570 commented 1 year ago

Is there a way to make this awesome statemanagement library compatible with SSR?

Now React throws this warning:

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

BTW thx for making a alternative for "use-global-hook" this library is way beter and migrating was quite easy thanks to you.

ElRatonDeFuego commented 1 year ago

Hi, glad you find the lib useful. When I coded it, the company I worked for asked for it to be placed with the company's public repos, but I'm no longer with this company. I will check if I can still commit to the repo, and otherwise will need to fork it in order to update the lib. Or you can have a go at it yourself if you feel like it. Someone else also asked for SSR compatibility a while ago, so I will have a look - I don't think it should be too much work. But I can't commit to a date right now, sorry.

On 31 December 2022 14:54:44 CET, Kasper @.***> wrote:

Is there a way to make this awesome statemanagement library compatible with SSR?

Now React throws this warning:

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

-- Reply to this email directly or view it on GitHub: https://github.com/qosenergy/shared-store-hook/issues/7 You are receiving this because you are subscribed to this thread.

Message ID: @.***>

Diabl0570 commented 1 year ago

Understandable.

I cloned the repo and added a test that uses https://react-hooks-testing-library.com/ to test the hook as a serverside hook.

It seems dat just replacing useLayoutEffect for useEffect is already enough to make it work server side.

idk how you would like to proceed. Here is my test case for the serverside rendering (maybe it saves you some time)

edit: see pull request: https://github.com/qosenergy/shared-store-hook/pull/8

ElRatonDeFuego commented 1 year ago

I've just quickly tried the lib with SSR and it worked OK for me, but I haven't looked at your code yet, something may be different.

I had replaced useEffect with useLayoutEffect on purpose to avoid a race condition issue, see here: https://github.com/qosenergy/shared-store-hook/issues/3

I wouldn't like to just revert to using useEffect, as this issue would reappear.

I will try to look at your code in the coming days/week to understand the problem you've faced. Again, I can't commit to a date as I'm pretty busy with my work at Sonar, now, sorry. But I would like to get to the bottom of this.

Diabl0570 commented 1 year ago

Right I understand and remembered something about SSR; useIsomorphicLayoutEffect If you want more info on the subject: https://medium.com/@alexandereardon/uselayouteffect-and-ssr-192986cdcf7a

But this is al you need to know:

In this technique (hack), we conditionally return useLayoutEffect or useEffect based on whether we are running in the browser or not. Both useEffect and useLayoutEffect have the same API so your type system should be all good.

This hack is currently being used in react-redux and react-beautiful-dnd .

Edit: I tried using this method but the jest-tests failed and I currently don't have any more time to look into it further.

ElRatonDeFuego commented 1 year ago

Thanks for the link, weird that I didn't see this warning in my test. Will investigate why, and use the conditional test if needed. In the meantime I'd suggest you keep using your fork, as I'm not sure when I'll be getting around to actually doing this.