React数组映射引发性能问题:电商产品组件优化咨询
React产品卡片组件性能优化方案
下面是针对你的组件性能问题的具体优化方案,尽量保留原有组件结构的同时解决性能瓶颈:
1. 修复无限重复请求问题
原代码中useEffect未设置依赖数组,导致组件每次渲染都会重新发起接口请求,不仅浪费资源还会触发多次状态更新。
修改代码:
useEffect(() => { axios.get('http://localhost:8080/products/get/') .then(res => { setRows(res.data); }).catch(err => { console.log(err); }); }, []); // 添加空依赖数组,仅组件挂载时请求一次
2. 避免每次渲染重复执行排序
原代码在渲染阶段调用rows.sort(),会导致组件每次render都重新排序数组,增加不必要的计算开销。
方案一:获取数据时一次性排序
useEffect(() => { axios.get('http://localhost:8080/products/get/') .then(res => { // 数据返回后立即排序,仅执行一次 const sortedRows = [...res.data].sort((a, b) => a.name.localeCompare(b.name)); setRows(sortedRows); }).catch(err => { console.log(err); }); }, []);
方案二:用useMemo缓存排序结果(适合后续有数据更新的场景)
import React, { useState, useEffect, useMemo } from 'react'; // ... const sortedRows = useMemo(() => { return [...rows].sort((a, b) => a.name.localeCompare(b.name)); }, [rows]); // 仅当rows变化时重新排序 // 渲染时替换为sortedRows return ( sortedRows.map(...) )
3. 优化移动端判断逻辑
原代码中isMobile每次渲染都会重新计算,且未监听窗口大小变化,导致判断结果不实时且浪费计算资源。
修改代码:
const [isMobile, setIsMobile] = useState(window.innerWidth < 768); useEffect(() => { const handleResize = () => { setIsMobile(window.innerWidth < 768); }; window.addEventListener('resize', handleResize); // 组件卸载时清理监听 return () => window.removeEventListener('resize', handleResize); }, []);
4. 替换index为唯一key
使用index作为列表key会导致React在列表更新时复用错误元素,触发不必要的重渲染和DOM操作,改用产品唯一ID(如row.id)作为key。
修改代码:
// 假设每个产品有id字段,替换index为row.id .map((row) => { return ( isMobile ? ( <div key={row.id} class={`${sidebar ? 'border-0' : 'border'} relative mt-6 py-8 px-5 rounded`} > // ... 原有内容不变 </div> ) : ( <div key={row.id} class="flex mt-6 py-8 px-5 border rounded"> // ... 原有内容不变 </div> ) ) })
5. 缓存MUI Button的sx属性
原代码中每次渲染都会创建新的sx对象,导致MUI Button组件频繁触发重渲染,将sx属性提取为组件外部的常量。
修改代码:
// 组件外部定义常量样式 const viewProductBtnDisabledSx = { opacity: 0.5, bgcolor: '#6366f1', textTransform: 'none', width: '100%', ':hover': { backgroundColor: '#4f46e5', }, }; const viewProductBtnEnabledSx = { opacity: 1, bgcolor: '#6366f1', textTransform: 'none', width: '100%', ':hover': { backgroundColor: '#4f46e5', }, }; const addToCartBtnSx = { border: '1px solid #38bdf8', color: '#38bdf8', textTransform: 'none', width: '100%', ':hover': { color: '#ffffff', backgroundColor: '#38bdf8', }, }; export default function ProductCard(props) { // ... 组件内部代码 // 使用预定义的sx常量 {sidebar && isntDesktop ? ( <Button type="submit" variant="contained" sx={viewProductBtnDisabledSx} > View product </Button> ) : ( <Button type="submit" variant="contained" sx={viewProductBtnEnabledSx} > View product </Button> )} <Button type="submit" sx={addToCartBtnSx} > Add to cart </Button> }
6. 可选:图片懒加载
给产品图片添加loading="lazy"属性,延迟加载未进入视口的图片,提升页面初始加载速度。
修改代码:
<img src={row.image} alt="product" class={`${sidebar ? 'opacity-50' : 'opacity-100'} mt-4 min-w-[125px] sm:w-[300px] h-auto`} loading="lazy" // 添加懒加载属性 />
内容的提问来源于stack exchange,提问作者Josh Haywood
相关产品推荐
相关产品推荐

