We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
参考文章:useMemo vs. useEffect + useState
在项目开发中突发奇想有了一个思考:当我们在数据更新触发重渲染的过程中,使用 useMemo 好还是用的比较普遍的 useEffect + useState 好呢?假设我们接收到了一个数据的变动,我们需要在该数据基础上对数据进行重新组织,然后更新视图,则以上两种方法会有各自一套不同的渲染逻辑:
useMemo
useEffect + useState
useState
setState()
useEffect
useMemo callback
useEffect 和 useState 将在每次更改时导致额外的渲染:
举个例子:
function expensiveCalculation(x) { return x + 1; };
我们初始化 x 为 0:
x
然后,如果我们将 x 更改为 2:
导致 useEffect 二次渲染而 useMemo 不发生二次渲染的原因在于:
❇️ useEffect 发生在页面渲染之后,而 useMemo 则是在页面渲染期间执行。
因此,若只是基于已有值进行改动,并缓存改动后的结果,可以优先考虑 useMemo
useMemo 与 Vue 中的 computed 计算属性使用场景类似,除此之外,他还可以作为一种性能优化的手段。
computed
虽然上述场景下 useMemo 看上去是最佳实践,但 useEffect + useState 在某些场景下仍然是较优的一个选择:
在一些长时间运行的同步场景中,useMemo 持有渲染线程,导致用户界面体验卡顿,而 useEffect + useState 是异步运算的,因此不会阻止渲染。
此外,useEffect + useState 可以处理一些带有异步副作用的逻辑,而这些是 useMemo 处理不了的。
参照官方文档说明:传入 useMemo 的函数会在渲染期间执行。请不要在这个函数内部执行不应该在渲染期间内执行的操作,诸如副作用这类的操作属于 useEffect 的适用范畴,而不是 useMemo。
所以,当 useMemo 记忆化函数中存在副作用时,我们应当使用 useEffect + useState。useEffect + useState 在要计算的事物是异步的情况下是正确的解决方案,因为无论如何该值在当前渲染中都不可用。
useEffect 是一个集体调用,无论是否异步,它是在所有组件渲染后收集的。
useLayoutEffect 是一个集体调用,但它同步发生在页面渲染更新前。
useLayoutEffect
useMemo 是一个本地调用,它只与这个组件有关。可以将 useMemo 视为一个具有使用上次更新结果的赋值语句。
这意味着,useMemo 更紧急,然后是 useLayoutEffect,最后是 useEffect。
💡 useEffect 和 useMemo 触发时机的差异,引出了另一个值得思考的点:相比于 useMemo ,useEffect 可以获取到更新后的 DOM 节点 (但还未可视化),因此在处理与 DOM 节点有关的操作时更具优势。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
useMemo vs. useEffect + useState
参考文章:useMemo vs. useEffect + useState
❇️ 前言
在项目开发中突发奇想有了一个思考:当我们在数据更新触发重渲染的过程中,使用
useMemo
好还是用的比较普遍的useEffect + useState
好呢?假设我们接收到了一个数据的变动,我们需要在该数据基础上对数据进行重新组织,然后更新视图,则以上两种方法会有各自一套不同的渲染逻辑:useEffect + useState
:用useState
重新创建一个变量来维护更新后的数据,将原数据处理完毕后setState()
存入到该变量中并触发重渲染,useEffect
捕获到依赖项发生变化,基于新数据更新视图。useMemo
:基于 callbcak 返回一个值作为变量进行维护,同时提供一个依赖数组选项,当依赖选项发生改变时,会同步触发useMemo callback
重新计算并更新变量。✅ Compare Result
🔆
useEffect + useState
会产生额外的渲染useEffect
和useState
将在每次更改时导致额外的渲染:举个例子:
我们初始化
x
为 0:useMemo
版本会立即呈现 1,因为它基于 x 进行初始化并同步更新数据然后,如果我们将 x 更改为 2:
useMemo
运行并呈现 3useEffect
版本运行,再次渲染 1,然后效果触发,组件以正确的值 3 重新运行。导致
useEffect
二次渲染而useMemo
不发生二次渲染的原因在于:❇️
useEffect
发生在页面渲染之后,而useMemo
则是在页面渲染期间执行。💡 总结
useEffect
版本会导致两倍的渲染量,这对性能不利。useMemo
版本更简洁、更易读。它不会引入不必要的可变状态,并且移动部件更少。因此,若只是基于已有值进行改动,并缓存改动后的结果,可以优先考虑
useMemo
🔆
useEffect
异步更新虽然上述场景下
useMemo
看上去是最佳实践,但useEffect + useState
在某些场景下仍然是较优的一个选择:在一些长时间运行的同步场景中,
useMemo
持有渲染线程,导致用户界面体验卡顿,而useEffect + useState
是异步运算的,因此不会阻止渲染。此外,
useEffect + useState
可以处理一些带有异步副作用的逻辑,而这些是useMemo
处理不了的。所以,当
useMemo
记忆化函数中存在副作用时,我们应当使用useEffect + useState
。useEffect + useState
在要计算的事物是异步的情况下是正确的解决方案,因为无论如何该值在当前渲染中都不可用。🔆
useEffect
与useMemo
的触发时机useEffect
是一个集体调用,无论是否异步,它是在所有组件渲染后收集的。useLayoutEffect
是一个集体调用,但它同步发生在页面渲染更新前。useMemo
是一个本地调用,它只与这个组件有关。可以将useMemo
视为一个具有使用上次更新结果的赋值语句。💡
useEffect
和useMemo
触发时机的差异,引出了另一个值得思考的点:相比于useMemo
,useEffect
可以获取到更新后的 DOM 节点 (但还未可视化),因此在处理与 DOM 节点有关的操作时更具优势。❇️ 总结
useEffect + useState
useMemo
The text was updated successfully, but these errors were encountered: