You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 22:25:23