Context lost on HMR
I'm having an issue with the state of a Solid context getting lost on HMR.
This makes sense because the module that calls
createContext
is being reloaded, and the call is a module level statement, which is pretty normal I think.
But from this https://github.com/solidjs/solid-refresh/issues/15 it looks like solid-refresh should know how to preserve the state.
Is there some good practive that I'm missing to make this work?GitHub
Contexts become undefined during HMR · Issue #15 · solidjs/solid-re...
It seems during HMR any useContext() becomes undefined, potentially breaking components that trust on a context being always unavailable or set up without defaults, which in turn breaks the hot rel...
13 Replies
Reloading the module causes the context object to change identity. Try splitting out the createContext into a separate definition file, this should help.
It's already in a different file but that file is getting reloaded when I make a change to a component file that (indirectly) imports it. I guess I need to understand more about how vite HMR decides which modules to reload.
I solved this (well, me and Claude 3.5 solved it). In case it's helpful to others, here's the solution (I which discord would publish these threads on the web so this stuff was more findable)
if you have the context creation in the same file as the
useContext
call, the bug can occur
which is why I always recommend isolating createContext into a separate file
this is too unsafe for a fixI'm not understanding how this helps, because vite follows the import chains and reloads those modules too. I already have it in a separate file.
Ohh sorry I scanned what you said too quickly
I do have the create and use in the same file - I'll try separating
so that createContext doesn't have to re-run on a TSX file, which causes different calls.
TBF HMR for createContext is supported (useContext actually looks up by context ID so the HMR just carries over the already created one) but I guess the file extension is limited.
I might have to re-imagine things here, probably needs discussion with Ryan
I tried moving the createContext into a different file (.ts) and I'm still losing state on hot reload
A console.log in the new file with createContext shows that the file is getting reloaded - not sure if that's expected or not
Also make sure there's no import cycles
They can destroy hmr completely
Yes - I got rid of all those recently for exactly that reason
@lxsmnsyc 🤖 anything else I can try, given moving createContext to a .ts did not help?
what does your file with createContext look like
honestly it always worked for me
I've reverted back to my createHotStableContext now, but what I tried was a one-line module, just
export const MyContext = createContext()
I think I might still have issues with import cycles. I thought I could use dynamic imports to avoid them, but it looks like any kind of import cycle is a problem, not just static ones.
It's tricky because my UI is fundamentally recursive (tree editor). I will look into dependency injection to resolveI don't see how this would not work except if you have cyclic imports, as you mentioned
once a module is unchanged it will always remain unchanged
Doesn't HMR re-execute all recursively included modules, even if they haven't changed?
no, it only reloads the changed module (or those modules that actually wanted to be reloaded)
by default, it doesn't reload unchanged modules