React使用useState出现过多重渲染,attList等函数重复执行问题排查
重复渲染原因分析
- 顶层直接调用接口函数触发死循环
你把attList(1,1)直接写在了组件函数的顶层,没有放在useEffect钩子中。React组件每次渲染时都会从头到尾执行一遍函数体内的所有代码,所以每次渲染都会触发一次attList调用,接口请求成功后执行setMainData更新状态,状态更新又会触发组件重新渲染,重新渲染又会再次调用attList,就形成了「渲染→调接口→更新状态→再渲染」的无限循环,这是重复执行的核心原因。 - 未缓存的计算逻辑每次渲染重复执行
currentPosts函数直接写在组件体内,并且在JSX渲染时直接调用执行。只要组件触发重渲染,这个函数就会跟着重新执行一次。如果indexOfFirst、indexOfLast这些依赖没有做缓存,或者返回的切片数组每次都是新的引用,还会进一步触发子组件Item的重复渲染。 - 未缓存的函数与变量导致额外重渲染
你当前定义的attList、currentPosts函数每次组件渲染都会生成新的函数引用,如果后续有将这些函数作为props传递给子组件的场景,也会触发子组件的不必要重渲染。
修复方案
- 把接口调用逻辑放进
useEffect,指定空依赖数组保证只在组件挂载时执行一次:
// 仅组件挂载时执行一次接口请求 useEffect(() => { attList(1, 1).then(data => {console.log("then");}) }, [])
- 用
useMemo缓存切片后的列表,避免每次渲染都重新执行切片逻辑:
const currentPosts = useMemo(() => { return maindata.slice(indexOfFirst, indexOfLast); }, [maindata, indexOfFirst, indexOfLast])
调整后把JSX里的rlist参数直接改成rlist={currentPosts}即可。
- 如果有需要把函数传递给子组件的场景,可以用
useCallback缓存函数引用,减少子组件不必要的重渲染。
内容的提问来源于stack exchange,提问作者C12H22O12
相关产品推荐
相关产品推荐

