面试题答案
一键面试memo
工作原理
memo
是 React 提供的一个高阶组件,用于对函数式组件进行浅比较优化。当组件的 props 没有发生变化时,memo
会阻止组件重新渲染。它会对新旧 props 进行浅比较,如果浅比较结果为相等(即新旧 props 引用相同或所有一级属性的值相同),则不会触发重新渲染,从而提高性能。
useCallback
工作原理
useCallback
是一个 React Hook,它返回一个 memoized 回调函数。其原理是只有当指定的依赖项数组中的值发生变化时,才会返回新的回调函数。否则,会返回上一次缓存的回调函数引用。这样在依赖不变的情况下,回调函数的引用保持不变,有助于避免不必要的重新渲染。
结合使用场景
在以下场景下需要结合使用 memo
和 useCallback
:当一个组件接收回调函数作为 props,并且该组件被 memo
包裹以防止不必要的重新渲染时,如果回调函数每次渲染都变化,会导致 memo
失效。此时使用 useCallback
来缓存回调函数,确保其引用稳定,让 memo
能够正常工作。
列表组件优化示例
对于一个列表组件,列表项可点击且点击后触发复杂计算函数的场景,优化步骤如下:
- 列表项组件使用
memo
:
这里const ListItem = React.memo(({ item, onClick }) => { return ( <li onClick={() => onClick(item)}> {item.text} </li> ); });
ListItem
组件使用memo
包裹,当item
和onClick
props 没有变化时,不会重新渲染。 - 父组件中使用
useCallback
:
在父组件import React, { useCallback } from'react'; import ListItem from './ListItem'; const complexCalculation = (item) => { // 复杂计算逻辑 return result; }; const ListComponent = () => { const items = [/* 列表数据 */]; const handleClick = useCallback((item) => { complexCalculation(item); }, []); return ( <ul> {items.map((item) => ( <ListItem key={item.id} item={item} onClick={handleClick} /> ))} </ul> ); }; export default ListComponent;
ListComponent
中,使用useCallback
来 memoizehandleClick
回调函数。依赖项数组为空,意味着只要组件挂载,handleClick
的引用就不会改变。这样传递给ListItem
的onClick
prop 引用稳定,ListItem
的memo
就能正常工作,避免因onClick
变化导致的不必要渲染,从而提升性能。