Search code examples
typescriptsolid-js

Solid.js: How to put useContext within a provider coming from an external event


const CounterContext = createContext();

export function CounterProvider(props) {
  const [count, setCount] = createSignal(0),
    store = [
      count
    ];

  return (
    <CounterContext.Provider value={store}>
      {props.children}
    </CounterContext.Provider>
  );
}

export function useCounter() { return useContext(CounterContext); }

I want to use this useCounter outside of the provider, after an external event like a setTimeout or an incoming Websocket message.

setTimeout(() => {
  const [count] = useCounter();
  createEffect(on(count, () => {
    console.log(count)
  }))
})

This seems like a bad idea, but I have this in my application code, and I don't know how to restructure my code to avoid this.


Solution

  • Generally I would look at getting the useContext call under the provider if possible or under a effect under the main rendering that is guarded. Yes you could use more advanced APIs like runWithOwner, but it probably will lead to other hiccups later if things are structured in a way you wouldn't be able to do that.

    Normally the fix involves creating a signal that wires up the dynamic behavior you want synchronously, and then triggers it by setting the signal from the timeout.