useContext from function dynamically imported
I'm building a keyboard shortcut management system and wanted to be able to dynamically import the action associated with a keybinding. Some of these keybindings may use a context so I've intentionally put the keyboard shortcut manager provider inside of all other providers.
action: () => import("../actions/switchColorScheme")
and in my index file:
I'm getting an error when trying to useContext()
in the action file's default function. Is that expected or is there a correct way of doing this? I thought that intentionally nesting the contexts where they'd normally work would be fine.27 Replies
For reference, this is the function I'm trying to execute:
I have also verified
useColorScheme
works in components, as well as the KeyboardShortcutManagerProvider
Also trying this with a normal function attached to the action ends up with the same error so maybe this is just a bad pattern? 🤔it depends where you're calling the function, you need to be doing so in a place that has access to the context
like in a component body
ah, I thought as long as the call site was within the context it would work
SomeContext -> KeyboardContext -> calls action() -> action impl -> useSomeContextContext
depends how the context calls it
hmm, could you elaborate please?
can you show how
KeyboardContext
calls action
?And: What’s the error message?
there is some business logic in here but essentially it will find the appropriate action based on the keys that are down in the
keydown
event
this is inside of a provider, which is nested under the context that it needs to use within the actionthis is calling
action
inside an event handler, which is executed outside of the ownership scope
even though the handler is defined inside a context, it depends where it's calledah, so can i bind the scope with an arrow function in this situation?
nah the equivalent would be getting the
Owner
of the context component with getOwner
and using runWithOwner
so the handler has access to the context, but personally i'd try find a way to not have to do that@Madaxen86 FWIW this is the error
I guess I'll need to think on this a bit more but I was trying to decouple the impl of action from the keyboard shortcut provider
i'd probably just pass the values into the action handler
the value of
getOwner
?
this works fine but idk if it is "proper" so to speaknah i'd just put the result of
useColorScheme
into the arguments of action
itselfI was thinking about something like that but then I'm in the position of the keyboard shortcut provider having to know about every possible context/arg of each action
For some additional context I have things laid out like this atm:
This naming is probs not great but I'm drawing inspriation from Unreal Engine's Enhanced Input System so 🤷🏼♂️ idk for now.
the
KeyboardShortcutManagerProvider
is just a binding between the user's keyboard inputs and the InputMappingContext (again probs a bad name for JS world)
I guess I'm just not seeing how I could call any of the actions which may or may not use any context within the app from the keyboard shortcut provider without somehow coupling every argument type to the provider
Maybe basing this loosely on game development practices was a bad idea too lol 🤷🏼♂️I have something like this for my project and I just made a global shortcut manager
Would you mind sharing your implementation or some details?
Or if you're up for it I could hop into a call and share what I have too
I'm just exporting my manager from a file like this
then I can just do
And are you able to use other contexts in the function without issue?
I'm not familiar with using multiple
createRoot
s yet as I'm pretty new to solid
hmm I haven't tested it but in general doing
useContext
inside an event handler doesn't work :P
let me test
nope
does not workThat's what @Brendonovich was saying which makes sense after his explanation but now it is forcing me to rethink everything or couple things tightly
TL;DR; I want to run arbitrary code within the shortcut manager and have access to any of the contexts
Hmm
Thanks to @Brendonovich for bringing up the concept of owners, this is now working but IDK if it is "proper" or "best practice" to do something like this
Yeah just tested it by adding something similar
I'm doing the
runWithOwner(getOwner(), action)
as part of the addCombo
except I'm reading getOwner
outside
so like
fwiw I think this is fine to donice, I think in order to decouple the arbitrary code, it needs this behavior
thanks to everyone for talking this through with me 😃