Recoil icon indicating copy to clipboard operation
Recoil copied to clipboard

[SSR][NextJS] status of Recoil with SSR and Next.js

Open carlos-lm opened this issue 4 years ago • 9 comments

Hi guys, I'll like to give a try to recoil in my company along with Nextjs and SSR, I'm trying to find information about this integration but I just found bugs and issues, someone is using Nextjs,SSR and recoil right now?...do you know where I can get more info about this?...thank you so much

carlos-lm avatar Nov 19 '20 16:11 carlos-lm

Maybe you can have a try on concent, it is also support SSR & Nextjs

fantasticsoul avatar Nov 20 '20 03:11 fantasticsoul

Also #733

drarmstr avatar Nov 25 '20 21:11 drarmstr

I've been using Next.js and Recoil fine w/ SSR in a few of my projects. Haven't found a good way to initialize state on server side yet though :( Is there anything in particular you're concerned about?

caelinsutch avatar Dec 28 '20 21:12 caelinsutch

I put together a minimal example of using getServerSideProps to set initial Recoil values - can't be sure any of this is good practice, but it works. The only real trick here is keeping track of every initializable atom in a separate dict (because set requires a reference to the atom, not just its key).

https://gist.github.com/spro/a4ccb681ba05abde9943fdfcd9bf497d

spro avatar Jan 05 '21 00:01 spro

Interesting @spro, you may want to consider if Atom Effects could be used here to avoid maintaining a manual lookup of atoms by key and allowing this to work with atom families?

I put together a minimal example of using getServerSideProps to set initial Recoil values - can't be sure any of this is good practice, but it works. The only real trick here is keeping track of every initializable atom in a separate dict (because set requires a reference to the atom, not just its key).

https://gist.github.com/spro/a4ccb681ba05abde9943fdfcd9bf497d

drarmstr avatar Jan 05 '21 05:01 drarmstr

Looking into it but the trouble (in the Next.js case at least) is that the server-supplied data is passed in as props to the page components. Only thing I can think of is something funky like set a mutable global variable when the component mounts as a component effect, and access that with atom effects.

Edit: Alas, component effects are not run during SSR so the above approach wouldn't work.

spro avatar Jan 05 '21 21:01 spro

I forgot about useMemo. Here https://gist.github.com/spro/280e06758099a05b3bfb6e876e919f2e is a functionally equivalent version using atom effects.

The danger with this approach is that the mutable global variable is actually kept in memory by the server - so if it's not completely replaced, data from previous page loads will stick around. A previous iteration using Object.assign had this problem.

spro avatar Jan 05 '21 23:01 spro

Are there any updates on this? I literally cannot find any information about initialising the state per page in for example the getStaticProps at build time for static rendering. Or am i missing something?

tiersept avatar Oct 02 '22 09:10 tiersept

I struggled with this for the last couple months too (and found this thread some time ago), but I figured out a pattern that works and finally got around to wrapping this up in a small OSS project at https://github.com/nebrius/recoil-bootstrap.

If you'd rather write this yourself instead of using the library, the quick tl;dr is that I created special "root" atoms that act like intermediaries between the root component (aka the default export from a Next.js route file) and all our atoms. Bootstrap data is assigned to these root atoms at page load time. Then, we can create our actual atoms we want that are structured such that their default value is a selector that pulls from the root atom. There's some other fancy footwork needed to make sure these all load synchronously so that they show up in SSR (gotta use several of the snapshot APIs), but it's possible using only the current public Recoil APIs.

Hope this helps.

nebrius avatar Jun 24 '23 04:06 nebrius