React组件频繁重渲染排查:疑似数据获取引发的问题
解决React组件频繁重渲染及重复数据请求问题
问题根源
- 自定义Hook被当作普通函数调用:你写的
KPI_Stock_Utilisation包含useState和useEffect,属于React自定义Hook范畴,但你在组件渲染阶段直接把它当普通函数执行。每次组件渲染都会重新运行这个函数,创建全新的state实例,触发useEffect发起请求,更新state后又会触发组件重新渲染,形成循环。 - 无意义的重复执行:组件每渲染一次就会调用一次
KPI_Stock_Utilisation(),导致console.log('data get')反复打印,同时组件自身的console.log('component render')也会跟着重复输出。
解决步骤
第一步:修正自定义Hook的写法(遵循React规范)
自定义Hook必须以use开头,这是React识别Hook的约定,同时确保内部逻辑只在组件挂载时执行一次:
import { useState, useEffect } from 'react'; import axios from 'axios'; // 改名成符合规范的自定义Hook export function useKPIStockUtilisation() { const [kpiStockUtilisation, setKpiStockUtilisation] = useState([{}]); useEffect(() => { axios.get("http://localhost:5137/KPI_Stock_Utilisation") .then((response) => { setKpiStockUtilisation(response.data); }) .catch(err => { // 建议添加错误处理,避免请求失败导致的异常 console.error('库存利用率数据获取失败:', err); }); }, []); // 空依赖数组确保仅在组件挂载时执行一次请求 console.log('data get'); return kpiStockUtilisation; }
第二步:在组件中正确使用自定义Hook
不再直接调用函数,而是通过Hook的方式获取数据:
import React, { useMemo } from "react"; import { useKPIStockUtilisation } from "../../Data/data"; // 可选:用React.memo包裹组件,避免父组件更新时无意义重渲染 export default React.memo(function WarehouseUtilisChart(props) { // 正确使用自定义Hook const kpiStockUtilisations = useKPIStockUtilisation(); // 用useMemo缓存计算结果,避免每次渲染重复计算 const stockUtilisation = useMemo(() => { return (kpiStockUtilisations.length / 402) * 100; }, [kpiStockUtilisations.length]); console.log('component render'); return ( <div> {/* 直接渲染数组会显示[object Object],建议转成JSON或遍历渲染 */} <p>原始数据: {JSON.stringify(kpiStockUtilisations)}</p> <p>库存利用率: {stockUtilisation.toFixed(2)}%</p> </div> ); });
额外说明
- 如果开发环境下仍看到两次渲染日志,是React Strict Mode的机制:它会在开发环境刻意触发两次渲染,用于检测潜在的副作用问题,生产环境不会出现这个情况。
- 若组件还是频繁重渲染,检查父组件是否频繁更新状态/属性,此时
React.memo可以帮你过滤掉不必要的重渲染。
内容的提问来源于stack exchange,提问作者Chanka1021
相关产品推荐
相关产品推荐

