在从事前端开发工作时,您可能遇到过 useMemo。对于那些不熟悉它的人,我们将解释如何在 React 中使用 useMemo 以及最重要/突出的用例。
useMemo 是一个很棒的内置钩子,可以帮助提高网络应用程序的性能。我们知道,在React中,只要组件的状态或 props 发生变化,组件就会被渲染。
重新渲染的组件也将重新计算正在使用的函数。
因此,如果有繁重、昂贵的函数,性能可能会受到影响,因为它们必须每次都被计算。 useMemo 帮助记忆这些函数以优化性能。
为了理解useMemo,我们需要反思什么是memoization 。
如果有一个开销很大的函数,比如获取大量数据,memoization 是一种存储该函数结果的方法,这样就不必一遍又一遍地调用它。
useMemo 将采用它正在包装的函数,并缓存该函数的结果,以便在需要时可以将其提供给您,而无需重新进行计算。
作为内置钩子,您可以从 React 导入钩子并在顶层使用它。
然后,您可以通过声明一些常量或变量并将其分配给钩子的结果来使用 useMemo 包装昂贵的计算。
不要忘记添加依赖项,因为这是 useMemo 确定是否必须再次重新计算函数的方式。
如果您的依赖项发生变化,那么 useMemo 将知道重新计算该值,以便它始终缓存正确的结果。
import { useMemo } from 'react' ; function someExpensiveFunction ( n ) { return n * n; } function myFunction ( {n} ) { const result = useMemo( () => someExpensiveFunction(n), [n]); return ( < div > {result} </ div >
); }
例如,如果您将值 5 传递给
n
,它会缓存 25 的值。如果n
将值更改为 7,useMemo 知道它是一个依赖项,并将重新计算为 49 的值并缓存该结果。当您的前端应用程序向 API 发出请求时,这尤其有用。
这些请求可能会变得昂贵,尤其是当您要获取大量数据时。
也许您的应用程序有一些组件需要此数据,但您不想在每次呈现组件时都调用 API。
那么,使用 useMemo 缓存你的结果可能是你最好的选择。
import React, { useMemo } from 'react' ; import axios from 'axios' ; const ApiComponent = () => { const memoizedResults = useMemo( async () => { try { const apiResponse = await axios.get( 'http://apicall.com/somedata' ); return apiResponse.data; } catch (error) { return error; } }, []); return ( < div > {apiResponse} </ div >
) }
如您所见,我们的依赖项是空的,因为我们只希望它呈现一次,因为值实际上不会改变。我们只想在首次呈现时调用一次 API。
然后,此值将在后续渲染中重复使用。
尽管 hook 很有用,但经常使用 useMemo 不一定是个好主意。将您使用 useMemo 编写的每个函数包装起来以“保存”计算可能很诱人。
但是,在不需要时使用它实际上反而会减慢您的应用程序。
1. 琐碎的计算
如果你用 useMemo 包装的函数是一个简单的计算,那么使用 useMemo 的成本可能会更重要。
如果你能够确定你的函数的权重很小,例如 O(n) 时间,那么确定不需要 hook 是合适的。
2. 当你的函数可能影响外部状态和变量时
如果您的函数涉及对其他全局变量进行修改,或者依赖于它们,那么使用 useMemo 可能不是一个好主意。
如前所述,useMemo 仅在依赖项更改时才重新计算函数。
但是,如果函数使用的变量或调用不一定是依赖项更改,则它不会重新计算该值,从而导致缓存结果不正确。
你们中的一些人可能还熟悉 useCallback,它的用途与 useMemo 类似。本文不会深入探讨 useCallback,但我们会区分何时使用这两个函数。
useMemo 和 useCallback 很容易混淆,因为它们都是通过为您记忆某些内容来优化您的应用程序的钩子。然而,重要的是要注意他们记忆的东西是不同的。
在大多数情况下,useMemo 记忆值,而 useCallback 记忆函数。顾名思义,useCallback 用于记忆回调函数,尤其是那些作为 props 传递给子组件的回调函数。回调函数可以依赖于某些值或引用,这些值或引用会随着时间的推移而改变,这意味着对这些函数的更新将导致使用它们的组件重新渲染。因此,记忆它们可以帮助防止重新渲染,这可能会影响我们的优化。
然而,由于 useMemo 可以记忆函数和值,它可以用来代替 useCallback 钩子。尽管如此,重要的是要考虑您的情况的上下文并适当地使用钩子以按预期使用它们。
useMemo 总的来说……是一个很棒的、灵活的钩子,可以为你记住值并避免重新渲染。通过有策略地使用挂钩,您可以优化您的应用程序,减少计算量,并让用户拥有更快、更流畅的体验。
让 useMemo 为您的用户提供……难忘的体验!