反应:useEffect vs useMemo vs useState
React: useEffect vs useMemo vs useState
我试图在网上找到一个简明的答案,但运气不好。
关于 useEffect
、useMemo
和 useState
之间的区别,下列说法正确吗?
- 两者
useState
和 useMemo
都会记住渲染中的值。不同之处在于:
useMemo
不会导致重新渲染,而 useState
会
useMemo
仅在其依赖项(如果有)发生变化时运行,而setSomeState
(useState
返回的第二个数组项)没有这样的依赖项数组
-
useMemo
和 useEffect
仅在它们的依赖关系发生变化(如果有)时运行。不同之处在于:
useEffect
运行 after 渲染发生,而 useMemo
运行 before
还有其他我遗漏的主要区别吗?
你的观点基本正确,一些小的说明:
useState 导致 re-render 调用 setState 方法(数组中的第二个元素 returned)。它没有像 useMemo 或 useEffect 这样的依赖项。
useMemo 仅在其依赖数组中的元素发生变化时才重新计算一个值(如果没有依赖关系 - 即数组为空,它只会重新计算一次)。如果数组被遗漏,它将在每次渲染时重新计算。调用该函数不会导致 re-render。此外,它 运行s 在 组件渲染期间而不是之前。
useEffect 在每次渲染 之后 调用,如果其依赖数组中的元素已更改或数组被遗漏。如果数组为空,它只会在初始挂载时 运行 一次(如果你 return 一个清理函数则卸载)。
您可以随时查看 Hooks API Reference,我认为这是一份非常可靠的文档
useEffect(callback, [dependency])
的return值为void
,在render()
之后执行。
useMemo(callback, [dependency])
的 return 值不是 void
而是记忆值,它在 render()
. 期间执行
useEffect()
可以在以下情况下提供与 useMemo() 相同的优化:
- 在昂贵的计算中使用的状态变量(即 count1)是 useEffect 的唯一依赖项。
- 当我们不介意将昂贵的计算值存储在状态变量中时。
const [count1, setCount1] = useState(0);
const [expensiveValue, setExpensiveValue] = useState(null);
useEffect(() => {
console.log("I am performing expensive computation");
setExpensiveValue(((count1 * 1000) % 12.4) * 51000 - 4000);
}, [count1]);
- 唯一的区别是,useEffect() 使昂贵的计算值在
render()
之后可用,而 useMemo() 使该值在 render()
期间可用。
- 大多数时候这无关紧要,因为如果该值已计算用于在 UI、
useEffect()
和 useMemo()
中呈现,两者都会在浏览器完成之前使该值可用画.
useMemo
用于记忆属于组件但不一定属于组件状态的 calculations/values 例如依赖组件的验证、方法必须 return 一个值;
const validEmail = React.useMemo(() => validateEmail(email), [email])
/* Now use 'validEmail' variable across the component,
whereas 'useEffect' return value is void and only used for unmounting duties,
like unsubscribing from subscription e.g. removeInterval*/
Remember that the function passed to useMemo runs during rendering. Don’t do anything there that you wouldn’t normally do while rendering. For example, side effects belong in useEffect, not useMemo.
useEffect
Side effects:
Mutations, subscriptions, timers, logging, and
other side effects
setState
的 setTimeout
's setInterval
' ref
赋值,API 调用,或任何不执行繁重计算的东西都属于这里。
还要记住,优化是有代价的,因此 React 建议仅在需要 memoization/optimisation 时使用 useMemo
,而在其他情况下,在必要时依赖 useEffect
:
You may rely on useMemo as a performance optimization, not as a semantic guarantee.
In the future, React may choose to “forget” some previously memoized
values and recalculate them on next render, e.g. to free memory for
offscreen components. Write your code so that it still works without
useMemo — and then add it to optimize performance.
[state, setState] = useState()
that is 更新给定的状态变量,该变量在重新渲染期间保持稳定并调用附加到它的 setState
触发重新渲染。这个钩子的目的与上面两个钩子没有太大关系。
我试图在网上找到一个简明的答案,但运气不好。
关于 useEffect
、useMemo
和 useState
之间的区别,下列说法正确吗?
- 两者
useState
和useMemo
都会记住渲染中的值。不同之处在于:useMemo
不会导致重新渲染,而useState
会useMemo
仅在其依赖项(如果有)发生变化时运行,而setSomeState
(useState
返回的第二个数组项)没有这样的依赖项数组
-
useMemo
和useEffect
仅在它们的依赖关系发生变化(如果有)时运行。不同之处在于:useEffect
运行 after 渲染发生,而useMemo
运行 before
还有其他我遗漏的主要区别吗?
你的观点基本正确,一些小的说明:
useState 导致 re-render 调用 setState 方法(数组中的第二个元素 returned)。它没有像 useMemo 或 useEffect 这样的依赖项。
useMemo 仅在其依赖数组中的元素发生变化时才重新计算一个值(如果没有依赖关系 - 即数组为空,它只会重新计算一次)。如果数组被遗漏,它将在每次渲染时重新计算。调用该函数不会导致 re-render。此外,它 运行s 在 组件渲染期间而不是之前。
useEffect 在每次渲染 之后 调用,如果其依赖数组中的元素已更改或数组被遗漏。如果数组为空,它只会在初始挂载时 运行 一次(如果你 return 一个清理函数则卸载)。
您可以随时查看 Hooks API Reference,我认为这是一份非常可靠的文档
useEffect(callback, [dependency])
的return值为void
,在render()
之后执行。useMemo(callback, [dependency])
的 return 值不是void
而是记忆值,它在render()
. 期间执行
useEffect()
可以在以下情况下提供与 useMemo() 相同的优化:
- 在昂贵的计算中使用的状态变量(即 count1)是 useEffect 的唯一依赖项。
- 当我们不介意将昂贵的计算值存储在状态变量中时。
const [count1, setCount1] = useState(0);
const [expensiveValue, setExpensiveValue] = useState(null);
useEffect(() => {
console.log("I am performing expensive computation");
setExpensiveValue(((count1 * 1000) % 12.4) * 51000 - 4000);
}, [count1]);
- 唯一的区别是,useEffect() 使昂贵的计算值在
render()
之后可用,而 useMemo() 使该值在render()
期间可用。 - 大多数时候这无关紧要,因为如果该值已计算用于在 UI、
useEffect()
和useMemo()
中呈现,两者都会在浏览器完成之前使该值可用画.
useMemo
用于记忆属于组件但不一定属于组件状态的 calculations/values 例如依赖组件的验证、方法必须 return 一个值;
const validEmail = React.useMemo(() => validateEmail(email), [email])
/* Now use 'validEmail' variable across the component,
whereas 'useEffect' return value is void and only used for unmounting duties,
like unsubscribing from subscription e.g. removeInterval*/
Remember that the function passed to useMemo runs during rendering. Don’t do anything there that you wouldn’t normally do while rendering. For example, side effects belong in useEffect, not useMemo.
useEffect
Side effects:
Mutations, subscriptions, timers, logging, and other side effects
setState
的 setTimeout
's setInterval
' ref
赋值,API 调用,或任何不执行繁重计算的东西都属于这里。
还要记住,优化是有代价的,因此 React 建议仅在需要 memoization/optimisation 时使用 useMemo
,而在其他情况下,在必要时依赖 useEffect
:
You may rely on useMemo as a performance optimization, not as a semantic guarantee.
In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without useMemo — and then add it to optimize performance.
[state, setState] = useState()
that is 更新给定的状态变量,该变量在重新渲染期间保持稳定并调用附加到它的 setState
触发重新渲染。这个钩子的目的与上面两个钩子没有太大关系。