英文:
Using SolidJS context in async function
问题
以下是您要求的翻译:
"Is it possible to get the context value in an async function called from a component?
Even runWithOwner() gives me the default value of the context, not the enclosing value, after the first await.
const Ctx = createContext('default');
return <Ctx.Provider value='not-default' >{
(() => {
runWithOwner(getOwner()!, async () => {
const f = async () => {};
console.log('before', useContext(Ctx));
await f();
console.log('after', useContext(Ctx));
});
return '';
})()
}</Ctx.Provider >;
Tried enclosing the async call in runWithOwner()
Update: I 'solved' it by using signals instead of context. It's an import of a global variable either way, but signals work...
const [Sig, setSig] = createSignal('default');
const Ctx = createContext('default');
const f = async (where: string) => {
console.log(where, 'ctx', useContext(Ctx), 'sig', Sig());
};
return <Ctx.Provider value={setSig('not-default')} >{
(() => {
(async () => {
await f('first');
await f('broken');
})();
return '';
})()
}</Ctx.Provider >;
```"
<details>
<summary>英文:</summary>
Is it possible to get the context value in an async function called from a component?
Even runWithOwner() gives me the default value of the context, not the enclosing value, after the first await.
```typescript
const Ctx = createContext('default');
return <Ctx.Provider value={'not-default'} >{
(() => {
runWithOwner(getOwner()!, async () => {
const f = async () => {};
console.log('before', useContext(Ctx));
await f();
console.log('after', useContext(Ctx));
});
return '';
})()
}</Ctx.Provider >;
Tried enclosing the async call in runWithOwner()
Update: I 'solved' it by using signals instead of context. It's an import of a global variable either way, but signals work...
const [Sig, setSig] = createSignal('default');
const Ctx = createContext('default');
const f = async (where: string) => {
console.log(where, 'ctx', useContext(Ctx), 'sig', Sig());
};
return <Ctx.Provider value={setSig('not-default')} >{
(() => {
(async () => {
await f('first');
await f('broken');
})();
return '';
})()
}</Ctx.Provider >;
答案1
得分: 1
上下文值不是一个信号,而是一个驻留在当前所有者上的对象属性,因此在异步函数中访问它不是一个问题,也不需要 runWithOwner
。
问题在于你在通过 Ctx.Provider
设置新值之前,在异步作用域内捕获了该值。尝试通过一个变量来访问它,你将获得更新后的值。
import { createContext, useContext } from 'solid-js';
import { render } from 'solid-js/web';
const Ctx = createContext('default');
const Comp = () => {
const cxt = useContext(Ctx);
const run = () => {
setTimeout(() => console.log(cxt), 1000);
return null;
}
return run();
};
export const App = () => {
return (
<Ctx.Provider value='not-default' >
<div>{useContext(Ctx)}</div>
<Comp />
</Ctx.Provider>
);
};
render(() => <App />, document.body);
https://playground.solidjs.com/anonymous/ab5ca23c-9551-416e-8e37-ef2c50d20ab1
英文:
Context value is not a signal but an object property that resides on the current owner, so accessing it in an async function is not a problem and does not require runWithOwner
.
The problem is you are capturing the value inside an async scope before setting a new value through Ctx.Provider
. Try accessing it through a variable, you will get the updated value.
import { createContext, useContext } from 'solid-js';
import { render } from 'solid-js/web';
const Ctx = createContext('default');
const Comp = () => {
const cxt = useContext(Ctx);
const run = () => {
setTimeout(() => console.log(cxt), 1000);
return null;
}
return run();
};
export const App = () => {
return (
<Ctx.Provider value={'not-default'} >
<div>{useContext(Ctx)}</div>
<Comp />
</Ctx.Provider>
);
};
render(() => <App />, document.body);
https://playground.solidjs.com/anonymous/ab5ca23c-9551-416e-8e37-ef2c50d20ab1
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论