axios Map阵列导致性能问题响应

xa9qqrwz  于 2022-11-23  发布在  iOS
关注(0)|答案(1)|浏览(181)

我有一个大约100行的mySQL数据库,其中包含我在电子商务应用程序中列出的产品数据。
我使用Axios从后端SELECT *语句中获取行,将它们显示在前端,然后将它们保存为数组状态const [rows, setRows] = useState([]);,然后将这些行Map到表中的每一行,因此大约有100个Map。
我已经注意到,在这么多的结果中,性能已经开始成为一个问题,我也从Map数组中听到过类似的问题。我已经进行了基准测试和修补,发现这个组件是导致性能问题的原因。我希望有任何解决方案来提高我的组件的性能,而不需要太多地改变结构。
这是组件

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import Button from '@mui/material/Button';

export default function ProductCard(props) {
    const [rows, setRows] = useState([]);

    const isntDesktop = props.isntDesktop; //Constant from parent
    const isMobile = window.innerWidth < 768; //Checks if screen is smaller than mobile
    const sidebar = props.sidebar; //Sidebar state from parent component

    useEffect(() => {
        axios.get('http://localhost:8080/products/get/')
            .then(res => {
                setRows(res.data);
            }).catch(err => {
            console.log(err);
        });
    });

    return (
        rows
            .sort((a, b) => a.name.localeCompare(b.name)) 
            //Map products
            .map((row, index) => {
                return (
                    /* Adjust structure for mobile */
                    isMobile ? (
                        /* Product card */
                        <div 
                            key={index} 
                            class={`${
                                sidebar ? 'border-0' : 'border'
                            } relative mt-6 py-8 px-5 rounded`}
                        >
                            {/* Heading */}
                            <h2 class="text-2xl font-semibold tracking-wide text-gray-700">{row.name}</h2>
    
                            <div class="flex items-center sm:items-start space-x-5">
                                {/* Image */}
                                <img 
                                    src={row.image} 
                                    alt="product" 
                                    class={`${
                                        sidebar ? 'opacity-50' : 'opacity-100'
                                    } mt-4 min-w-[125px] sm:w-[300px] h-auto`} 
                                />
    
                                <div class="mt-4">
                                    {/* Price */}
                                    <p class="text-2xl sm:text-xl font-semibold sm:font-medium text-gray-600">£ {row.price}</p>
    
                                    {/* Keywords */}
                                    <ul class="ml-5 mt-2 space-y-1">
                                        <li class="list-disc text-gray-600">{row.keyword_one}</li>
                                        <li class="list-disc text-gray-600" >{row.keyword_two}</li>
                                        <li class="list-disc text-gray-600">{row.keyword_three}</li>
                                    </ul>
                                </div>
                            </div>
    
                            <div 
                                class={`${
                                    sidebar ? 'bg-none' : 'bg-gray-100'
                                } mt-4 py-2 px-4 flex justify-center space-x-2.5`}>
                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 text-sky-500">
                                    <path stroke-linecap="round" stroke-linejoin="round" d="M8.25 18.75a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h6m-9 0H3.375a1.125 1.125 0 01-1.125-1.125V14.25m17.25 4.5a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h1.125c.621 0 1.129-.504 1.09-1.124a17.902 17.902 0 00-3.213-9.193 2.056 2.056 0 00-1.58-.86H14.25M16.5 18.75h-2.25m0-11.177v-.958c0-.568-.422-1.048-.987-1.106a48.554 48.554 0 00-10.026 0 1.106 1.106 0 00-.987 1.106v7.635m12-6.677v6.677m0 4.5v-4.5m0 0h-12" />
                                </svg>
    
                                <label class="text-gray-600 text-sm">Free delivery on orders over £50</label>
                            </div>
    
                            <div class="mt-4 w-full mx-auto flex flex-col sm:flex-row space-y-2.5 sm:space-y-0 sm:space-x-2.5">
                                {sidebar && isntDesktop ? (
                                    <Button
                                        type="submit"
                                        variant="contained"
                                            sx={{
                                                opacity: 0.5,
                                                bgcolor: '#6366f1',
                                                textTransform: 'none',
                                                width: '100%',
    
                                                ':hover': {
                                                    backgroundColor: '#4f46e5',
                                                },
                                            }}
                                        >
                                        View product
                                    </Button> 
                                ) : (
                                    <Button
                                        type="submit"
                                        variant="contained"
                                            sx={{
                                                opacity: 1,
                                                bgcolor: '#6366f1',
                                                textTransform: 'none',
                                                width: '100%',
    
                                                ':hover': {
                                                    backgroundColor: '#4f46e5',
                                                },
                                            }}
                                        >
                                        View product
                                    </Button> 
                                )}
    
                                <Button
                                    type="submit"
                                        sx={{
                                            border: ' 1px solid #38bdf8',
                                            color: '#38bdf8',
                                            textTransform: 'none',
                                            width: '100%',
    
                                            ':hover': {
                                                color: '#ffffff',
                                                backgroundColor: '#38bdf8',
                                            },
                                        }}
                                    >
                                    Add to cart
                                </Button> 
                            </div>
                        </div>
                    ) : (
                        <div key={index} class="flex mt-6 py-8 px-5 border rounded">
                            {/* Image */}
                            <img src={row.image} alt="product" class="mr-4 w-[300px] h-auto" />
    
                            <div class="relative w-full px-5 items-center">
                                {/* Heading */}
                                <h2 class="text-2xl font-semibold tracking-wide text-gray-700">{row.name}</h2>
    
                                <div class="mt-8 flex justify-between">
                                    {/* Keywords */}
                                    <ul class="ml-5 space-y-1">
                                        <li class="list-disc text-gray-600">{row.keyword_one}</li>
                                        <li class="list-disc text-gray-600" >{row.keyword_two}</li>
                                        <li class="list-disc text-gray-600">{row.keyword_three}</li>
                                    </ul>
    
                                    {/* Promo */}
                                    <div class="flex flex-col ml-5">
                                        {/* Price */}
                                        <p class="text-xl font-medium text-gray-600">£ {row.price}</p>
    
                                        <div 
                                            class={`${
                                                sidebar ? 'bg-none' : 'bg-gray-100'
                                            } mt-4 py-2 px-4 flex space-x-2.5`}>
                                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6 text-sky-500">
                                                <path stroke-linecap="round" stroke-linejoin="round" d="M8.25 18.75a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h6m-9 0H3.375a1.125 1.125 0 01-1.125-1.125V14.25m17.25 4.5a1.5 1.5 0 01-3 0m3 0a1.5 1.5 0 00-3 0m3 0h1.125c.621 0 1.129-.504 1.09-1.124a17.902 17.902 0 00-3.213-9.193 2.056 2.056 0 00-1.58-.86H14.25M16.5 18.75h-2.25m0-11.177v-.958c0-.568-.422-1.048-.987-1.106a48.554 48.554 0 00-10.026 0 1.106 1.106 0 00-.987 1.106v7.635m12-6.677v6.677m0 4.5v-4.5m0 0h-12" />
                                            </svg>
    
                                            <label class="text-gray-600 text-sm">Free delivery on orders over £50</label>
                                        </div>
                                    </div>
                                </div>
    
                                <div class="absolute bottom-0 w-full pr-5 flex space-x-2.5">
                                    {sidebar && isntDesktop ? (
                                        <Button
                                            type="submit"
                                            variant="contained"
                                                sx={{
                                                    opacity: 0.5,
                                                    bgcolor: '#6366f1',
                                                    textTransform: 'none',
                                                    width: '100%',
    
                                                    ':hover': {
                                                        backgroundColor: '#4f46e5',
                                                    },
                                                }}
                                            >
                                            View product
                                        </Button> 
                                    ) : (
                                        <Button
                                            type="submit"
                                            variant="contained"
                                                sx={{
                                                    opacity: 1,
                                                    bgcolor: '#6366f1',
                                                    textTransform: 'none',
                                                    width: '100%',
    
                                                    ':hover': {
                                                        backgroundColor: '#4f46e5',
                                                    },
                                                }}
                                            >
                                            View product
                                        </Button> 
                                    )}
    
                                    <Button
                                        type="submit"
                                            sx={{
                                                border: ' 1px solid #38bdf8',
                                                color: '#38bdf8',
                                                textTransform: 'none',
                                                width: '100%',
    
                                                ':hover': {
                                                    color: '#ffffff',
                                                    backgroundColor: '#38bdf8',
                                                },
                                            }}
                                        >
                                        Add to cart
                                    </Button> 
                                </div>
                            </div>
                        </div>
                    )
                )
            })
    )
}
z0qdvdin

z0qdvdin1#

由于你(可能)希望只提取一次数据(在装载时),你必须在useEffect中添加一个空的依赖关系数组,以避免无休止地运行一个查询。你可以在这里阅读更多关于它的内容:https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects(在“注意”部分)。

useEffect(() => {
  axios.get('http://localhost:8080/products/get/').then(res => {
    setRows(res.data);
  }).catch(err => {
    console.log(err);
  });
}, [])

我看到你在render上呈现所有的数据,不幸的是,React is notoriously slow when it comes to rendering large lists。你可能需要考虑windowing你的数据,也就是当你的页面第一次加载时呈现一大块数据,当用户向下滚动时呈现更多的数据。有一个很棒的库可以为你处理这个问题:是的。
我希望这对你有帮助!

相关问题