【发布时间】:2020-08-28 07:03:41
【问题描述】:
场景相对简单:我们在远程服务器上进行了长时间运行的按需计算。我们想记住结果。即使我们从远程资源异步获取,这也不是副作用,因为我们只想将此计算的结果显示给用户,而且我们绝对不希望在每次渲染时都这样做。
问题:React.useMemo 好像不直接支持 Typescript 的 async/await 会返回一个promise:
//returns a promise:
let myMemoizedResult = React.useMemo(() => myLongAsyncFunction(args), [args])
//also returns a promise:
let myMemoizedResult = React.useMemo(() => (async () => await myLongAsyncFunction(args)), [args])
等待异步函数的结果并使用 React.useMemo 记忆结果的正确方法是什么?我在普通的 JS 中使用了常规的 Promise,但在这些类型的情况下仍然很难使用它们。
我尝试过其他方法,例如 memoize-one,但问题似乎是 this 上下文由于 React 函数组件的工作方式而发生变化 break the memoization,这就是我尝试使用的原因React.useMemo.
也许我正在尝试在此处的圆孔中安装一个方形钉 - 如果是这样的话,我也很高兴知道这一点。现在我可能只是要推出我自己的记忆功能。
编辑:我认为部分原因是我在使用 memoize-one 时犯了一个不同的愚蠢错误,但我仍然有兴趣在 React.memo 上知道答案。
这是一个 sn-p - 想法不是直接在渲染方法中使用记忆结果,而是作为以事件驱动的方式引用的东西,即在计算按钮单击时。
export const MyComponent: React.FC = () => {
let [arg, setArg] = React.useState('100');
let [result, setResult] = React.useState('Not yet calculated');
//My hang up at the moment is that myExpensiveResultObject is
//Promise<T> rather than T
let myExpensiveResultObject = React.useMemo(
async () => await SomeLongRunningApi(arg),
[arg]
);
const getResult = () => {
setResult(myExpensiveResultObject.interestingProperty);
}
return (
<div>
<p>Get your result:</p>
<input value={arg} onChange={e => setArg(e.target.value)}></input>
<button onClick={getResult}>Calculate</button>
<p>{`Result is ${result}`}</p>
</div>);
}
【问题讨论】:
-
为什么不
let myMemoizedResult = await React.useMemo(() => myLongAsyncFunction(args), [args]) -
@GazihanAlankus 这难道不会导致一个记忆化的承诺每次都回调到长时间运行的异步函数,即使 args 没有改变?
-
抱歉,我不了解 useMemo,我只是认为您通常遇到 async/await 问题。似乎他们反对您尝试做的事情:digitalocean.com/community/tutorials/…“您不会希望 useMemo 触发任何副作用或任何异步调用。将这两者包含在 useEffect 中会更有意义。”跨度>
-
感谢您的回复 - 这就是为什么我包含关于这不是副作用的部分。 useEffect 在每次渲染时检查参数,这不是这里想要的行为,因为用户可能希望在调用长时间运行的计算之前更改多个输入..
-
我认为我需要在原始问题中添加更多细节,以便更清楚地说明我想要做什么。
标签: reactjs async-await react-usememo