Replies: 1 comment 3 replies
-
Hey there! That is a great question @myou11. HMR/Fast Refresh support is always tricky since it depends so much on the build system. TMK, all the atomic libs struggle with hot reloading in React Native. Zedux and Recoil atoms are especially tricky since they can have side effects tied to them. It isn't always straightforward whether an atom should be completely force-destroyed and recreated or if only the atom's state should update during HMR. Additionally, sometimes you want the state to persist, other times you want it completely reset. No solution is perfect for every HMR situation. However, since the problem is amplified in RN (closing/reopening an app is much more annoying than refreshing a browser page), the best HMR approach for you is probably to force-destroy atoms when they update. Ecosystem-Level ApproachIn theory, a single HMR export default function App() {
const ecosystem = useMemo(() => createEcosystem({ id: 'root' }), [])
if (module.hot) {
module.hot.accept(() => {
ecosystem.reset()
})
}
return (
<EcosystemProvider ecosystem={ecosystem}>
<Routes />
</EcosystemProvider>
)
} Or it's probably better to move the import { getEcosystem } from '@zedux/react'
if (module.hot) {
module.hot.accept(() => {
getEcosystem('root')?.reset()
})
} This approach destroys every atom/selector in the ecosystem, triggers rerenders across your component tree, and recreates the entire atom graph during those rerenders - presumably using any hot updated atom templates. I'd never tried this global update approach, but I just ran it in a simple test repo and it looks like it works. Still, I can't be sure it'll work perfectly in every project. Atom-Level ApproachWhat I have done before is add an HMR code snippet to a specific atom when working with it. In Vite, my code looks like this: const self = injectSelf()
if (import.meta.hot) {
import.meta.hot.accept(newModule => {
self.destroy(true)
})
} Full example: export const testAtom = atom('test', () => {
const store = injectStore(0)
const self = injectSelf()
if (import.meta.hot) {
import.meta.hot.accept(newModule => {
self.template = newModule.testAtom // this mutation may be necessary when using selectors in the current version of Zedux
self.destroy(true)
})
}
return store
}) Now any changes to SummaryIf the global In practice, I find I spend more of my frontend dev time working on CSS and React component code. Once my state is in place, I don't change atoms much. At that point, I love the Dev X of atom state persisting across HMR updates. So if you do add HMR snippets, you may consider removing them at some point, once your state is well defined. |
Beta Was this translation helpful? Give feedback.
-
Hi there,
I am using Zedux with React Native and so far it's great! I am having trouble with getting my atom to update after I make changes to it and my app hot reloads. Sometimes I am updating one of my exported API functions and the update does not work unless I close the app and re-open it. If I add new state to the internal atom store, it is undefined until i close the app and re-open it.
I think the issue here is due to the atom already existing and since I updated the atom after it was already created, the atom is already using the original atom template.
I feel like you must have encountered this hot reloading issue in your apps, so I was wondering what are your recommended solutions?
Beta Was this translation helpful? Give feedback.
All reactions