如何使用带有异步功能的反应钩子“useMemo”?
Posted
技术标签:
【中文标题】如何使用带有异步功能的反应钩子“useMemo”?【英文标题】:How to use the react hook "useMemo" with asynchronous functions? 【发布时间】:2021-03-24 06:37:47 【问题描述】:我如何等待、解决/拒绝包装在反应钩子“useMemo”中的函数返回的承诺?
目前,我的代码如下所示:
// Get the persisted email/username
const persistedUsername = useMemo(async () =>
let username;
try
username = await AsyncStorage.getData(`@$ASYNC_STORAGE_KEY:username`);
catch
return username;
, []);
编辑
我想要实现的是在渲染组件之前获取数据,某种“componentWillMount”生命周期。我的两个选择是:
-
使用 useMemo 挂钩计算值以避免不必要的重新计算。
结合使用效果 + 使用状态。不是最好的主意,因为 useEffect 在组件绘制之后运行。
@DennisVash 在 cmets 中提出了这个问题的解决方案:
使用 useLayoutEffect 挂钩(某种 componentDidMount/componentDidUpdate)阻止所有视觉效果,其中代码在 DOM 更新后立即运行,但在浏览器有机会“绘制”这些更改之前。
如你所见,persistedUsername 仍然是一个promise(我不是在等待异步函数的结果)...
有什么想法吗?用这个钩子执行异步作业不是一个好主意吗?任何自定义钩子?
另外,以这种方式执行此操作与使用useEffect和useState相比有什么缺点?
useEffect 和 useState 也一样:
useEffect(() =>
// Get the persisted email/username
(async () =>
const persistedUsername = await AsyncStorage.getData(
`@$ASYNC_STORAGE_KEY:username`
);
emailOrUsernameInput.current.setText(persistedUsername);
)();
, []);
谢谢。
【问题讨论】:
那么在useMemo
中声明一个promise 并调用它?...
在我看来更像是 useEffect
和 useState
的用例
@thedude 是的,我也这么认为,但也许可以用 useMemo 来做到这一点(我从未将它用于异步操作)。
你知道useEffect
和useMemo
的区别吗?它们的用途不同,为什么要在 useMemo
中执行异步操作?你基本上是在问他们之间有什么区别?
@DennisVash useEffect 是在渲染之后执行动作,组件的最后一次执行,对吧?并使用Memo 执行权重动作,避免在每次渲染中重新计算它们。
【参考方案1】:
似乎问题是关于如何将componentWillMount
与钩子一起使用,这几乎等同于useLayoutEffect
(因为不推荐使用componentWillMount
)。
要了解更多信息,您应该不解决useMemo
中的async
操作,因为您将阻塞线程(并且JS 是单线程的)。
意思是,你会等到 promise 被解决,然后它会继续计算组件。
另一方面,像 useEffect
这样的异步钩子是更好的选择,因为它不会阻塞它。
【讨论】:
以上是关于如何使用带有异步功能的反应钩子“useMemo”?的主要内容,如果未能解决你的问题,请参考以下文章