React中带参数函数的useMemo/useCallback记忆化及重渲染问题
React useState高频重渲染与带参数函数记忆化解决方案
先揪出原代码的致命问题
你贴的代码里有两个直接导致崩溃的问题:
- 在
array.map的渲染逻辑里直接调用myFunction(item),这等于每次组件渲染都触发setExample更新状态,状态更新又触发渲染,形成无限循环,必然导致应用崩溃。 - map的回调函数没返回
<p>元素,渲染结果为空,等于白写。
用对钩子:useCallback才是缓存带参数函数的正确姿势
你之前误用了useMemo——它是用来缓存计算值的,而带参数的函数要缓存引用,得用useCallback。
修正后的完整代码
const MyComponent = () => { const [example, setExample] = useState({}); // 用useCallback缓存函数,依赖项只加setExample(React保证它稳定) const myFunction = useCallback((item) => { setExample(item); }, [setExample]); return ( <> {array.map((item, index) => ( // 重点:把状态更新放到事件里,比如点击触发,别在渲染时直接调用 <p key={index} onClick={() => myFunction(item)}> {item} </p> ))} </> ); };
核心逻辑说明
- useCallback的作用:只要依赖项(这里是
setExample)不变,它就会返回同一个函数引用,避免每次渲染都生成新的myFunction,如果这个函数要传给子组件,能大幅减少子组件的不必要重渲染。 - 绝对别在渲染阶段更新状态:渲染逻辑里只能做UI相关的计算,状态更新必须放到事件回调(点击、输入等)或者
useEffect这类副作用钩子中,否则必然触发无限重渲染。 - 关于依赖数组:
setExample是React官方保证的稳定函数,不会随组件渲染变化,所以把它放进依赖数组完全安全,不会导致函数频繁更新。
额外优化:缓存数组避免无意义遍历
如果你的array是从props传入或者动态生成的,可以用useMemo缓存数组引用,防止数组变化时触发不必要的map遍历:
const memoizedArray = useMemo(() => array, [/* array的实际依赖,比如props.data */]); // 之后用memoizedArray.map(...)
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

