You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jan 1, 2025. It is now read-only.
When I use and invoke useRecoilCallback synchronously in a component render, I get the following warning in the console: "Cannot update a component (Batcher) while rendering a different component (App)."
Here's some basic code that reproduces the bug:
import{useRef}from'react';import{RecoilRoot,atom,useRecoilCallback,useRecoilValue}from'recoil';constmyAtom=atom<number>({key: 'myAtom',});functionMyComponent(){constmyValue=useRecoilValue(myAtom);return<>{myValue}</>;}functionApp(){constsetBootstrapData=useRecoilCallback(({ snapshot, gotoSnapshot })=>()=>{gotoSnapshot(snapshot.map(({ set })=>{set(myAtom,10);}),);},[],);constisInitializedRef=useRef(false);if(!isInitializedRef.current){setBootstrapData();}return<MyComponent/>;}exportdefaultfunctionAppRoot(){return(<RecoilRoot><App/></RecoilRoot>);}
The reason I'm initializing my code this way, instead of using initializeState on RecoilRoot, is that I'm trying to build support for nested runtime bootstrap data as part of my library recoil-bootstrap. The full motivation can be read at https://github.com/nebrius/recoil-bootstrap#motivation. The tl;dr is that many Next.js apps have 2+ sets of bootstrap data that need to be initialized: one that is common to all pages, and one that is page specific.
The page specific one is the sticking point because the code with RecoilRoot is often in a common page wrapper (e.g. pages/_app.tsx in Next.js), and thus the only way to initialize page specific atoms inside of initializeState is to import every atom on every page, meaning we're initializing many atoms that aren't being used. (dynamic imports don't work cause tl;dr they're async and we have to initialize these synchronously for them to work in SSR). Thus, I need to initialize them separately elsewhere.
Notes:
I get the same error when I use useGotoSnapshot et. al. instead of useRecoilCallback
When I use and invoke
useRecoilCallback
synchronously in a component render, I get the following warning in the console: "Cannot update a component (Batcher
) while rendering a different component (App
)."Here's some basic code that reproduces the bug:
And here's a codesandbox link: https://codesandbox.io/s/keen-haibt-3ywssy?file=/src/App.tsx
The reason I'm initializing my code this way, instead of using
initializeState
onRecoilRoot
, is that I'm trying to build support for nested runtime bootstrap data as part of my library recoil-bootstrap. The full motivation can be read at https://github.com/nebrius/recoil-bootstrap#motivation. The tl;dr is that many Next.js apps have 2+ sets of bootstrap data that need to be initialized: one that is common to all pages, and one that is page specific.The page specific one is the sticking point because the code with
RecoilRoot
is often in a common page wrapper (e.g.pages/_app.tsx
in Next.js), and thus the only way to initialize page specific atoms inside ofinitializeState
is to import every atom on every page, meaning we're initializing many atoms that aren't being used. (dynamic imports don't work cause tl;dr they're async and we have to initialize these synchronously for them to work in SSR). Thus, I need to initialize them separately elsewhere.Notes:
useGotoSnapshot
et. al. instead ofuseRecoilCallback
xxx
) while rendering a different component (xxx
). #12. I'm not sure given that my use case seams to be a legitimate usage of Recoil's API, instead of me using it incorrectly like in that issue.The text was updated successfully, but these errors were encountered: