React组件重复发起API请求怎么优化首屏加载?
在开发产品列表页时发现,每次刷新页面都会看到两次相同的商品数据请求。我用useEffect在组件里调用axios.get,但好像不管是否依赖项变化都会触发。看浏览器网络请求发现首屏有重复的请求:
function ProductList() {
useEffect(() => {
axios.get('/api/products')
.then(res => setProducts(res.data));
}, []); // 这里是不是漏了什么?
return (
<div>
{products.map(product => (
<ProductCard key={product.id} product={product} />
))}
</div>
);
}
尝试给图片资源用了React.lazy动态导入,但首屏还是有很多重复请求。用Lighthouse检测发现仍有10+多余的JSON请求,应该怎么定位和解决这些重复的API调用呢?
先检查你的组件有没有被反复卸载/挂载,比如路由切换或者父组件状态变化导致的。如果是开发环境,React 18之后的strict mode会故意触发两次useEffect,模拟组件卸载再挂载的效果,用来帮你发现副作用问题。
另外你这个代码没有展示setProducts是怎么来的,假设是useState定义的,那问题不大。但要注意有没有可能在useEffect外面被调用,或者在then之前就触发了第二次请求。
可以临时加个console.log('useEffect触发'),看看是不是组件多实例导致的。比如ProductList被用了多次,或者父组件状态更新导致ProductList重复渲染。可以给useEffect里加个isMounted标记,或者用ref来标记是否已经请求过。
优化建议:
确保useEffect只执行一次,用ref控制
如果是SSR,可以考虑next.js的swr或者react-query,做客户端缓存
查看是否有多个ProductList组件同时挂载,可以用React.memo优化
网络面板看请求时间线,确认是不是同时发起的两个请求
举个例子: