Solid.js:如何将 useContext 放入来自外部事件的提供程序中

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); }

我想在提供商外部使用这个 useCounter,在 setTimeout 或传入的 Websocket 消息等外部事件之后。

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

这似乎是个坏主意,但我的应用程序代码中有这个,我不知道如何重构我的代码来避免这个。

您可以 运行 使用 runWithOwner 的异步代码来访问组件的上下文。

  // get component's owner
  const owner = getOwner();

  setTimeout(() => {
    // timeout happens after the owner has been assigned to null

    // in runWithOwner you have access to that owner's context
    runWithOwner(owner, () => {
      console.log(useContext(CounterContext));
    });
  });

runWithOwner 包装它还会使内部创建的计算与组件一起处置 - 如果您在根外部创建计算,它将永远不会被处置。

游乐场link:https://playground.solidjs.com/?hash=1366672288&version=1.3.16

一般来说,如果可能的话,我会考虑在提供程序下获取 useContext 调用,或者在受保护的主渲染下获取效果。是的,您可以使用更高级的 API,例如 runWithOwner,但如果事情的结构以您无法做到的方式进行,它可能会在以后导致其他问题。

通常,修复涉及创建一个信号来同步连接您想要的动态行为,然后通过设置超时信号来触发它。