简体   繁体   English

需要为反应中的每个击键调用一个 api,但响应可以有数千个对象

[英]Need to call an api for each key stroke in react, but the response can have thousands of objects

I am using react and axios for frontend, and nextjs with prisma for backend.我在前端使用 react 和 axios,在后端使用带有 prisma 的 nextjs。 I have in the database 4000 exercices that contain fitness exercices.我在数据库中有 4000 个包含健身练习的练习。 I want to create a function where by each key stroke, the api will look for the relevant exercice.我想创建一个 function,每次击键,api 都会查找相关的练习。 I finished creating it, but i have some issues:我完成了创建它,但我有一些问题:

  1. The main problem is that the response is delayed from the first keystrokes, because the payload response is tooo large.主要问题是响应从第一次击键开始延迟,因为负载响应太大。 I created a scrollable UL element to render the elements, because I want to get also the Gif images.我创建了一个可滚动的 UL 元素来呈现元素,因为我还想获得 Gif 图像。 So the elements, if the API will find those, will be rendered on the screen.因此,如果 API 能找到这些元素,它们就会呈现在屏幕上。

  2. If I add to each element an on click event, to select the exercice's Id, I get an error "too many re-rendering on the screen".如果我向每个元素添加一个点击事件,到 select 练习的 ID,我会收到错误消息“屏幕上重新渲染太多”。

How can I optimise the function, and how can I solve the error of too many re-render on the screen? function如何优化,如何解决屏幕上重新渲染太多的错误? Nextjs tells me that it will create an infinite loop.... Nextjs 告诉我它将创建一个无限循环....

The frontend looks like this:前端看起来像这样:

    const [open, setOpen] = useState(false);
    const [keyWord, setKeyWord] = useState('');
    const [array, setArray] = useState([]);
    const [exerciceId, setExerciceId] = useState('');


    // Add exercice
    const hadnleAddExercie = async event => {
        event.preventDefault();
        console.log('exercice added');
    }


    // Look for exercices
    const searchExercices = async event => {
        event.preventDefault();
        setKeyWord(event.target.value);
        const arrayExercices = await getExercicesByKeyWords(keyWord);
        setArray(arrayExercices);
        console.log(arrayExercices);
    }


<div className='flex mt-3 flex-col'>
                            <input onChange={searchExercices} required placeholder='Search by word...' className='border border-slate-400 p-1 rounded-md flex-1 max-w-sm my-2'/>    


                            <ul className='border border-slate-400 p-1 rounded-md max-w-sm my-2 max-h-52 overflow-scroll'>
                                {
                                    array.length > 1 && array.map(exercice => (
                                        <li key={exercice.id} className='flex flex-wrap p-2 bg-slate-200 m-2 items-center rounded-md'>
                                            <span><Image className='rounded-xl mr-2' priority width={40} height={40} src={exercice.gifUrl} alt={exercice.name}/></span>
                                            <span>{ exercice.name }</span>
                                        </li>
                                    ))
                                }
                            </ul>
                        </div>    

The backend Uses prisma and I use the OR clause to look for a word in different rows:后端使用 prisma,我使用 OR 子句在不同的行中查找单词:

export default async function handler(req, res) {

    try {

        const param = req.query.slug[0];
        console.log(param);

        // Get exercices where the two rows contains a single parametter
        const exercices = await prisma.exercices.findMany({
            where: {
                OR: [
                        {
                            name:   {
                            contains: param
                        }
                    },
        
                        {
                            target: {
                            contains: param
                        }
                    },

                        {
                            equipment: {
                            contains: param
                        }
                    }
                ]
            }
        });
        
        res.status(200).send(exercices);
    } 
    catch (error) {
        console.log(error);
        res.status(500).send(error);
    }
}

An example can be this:一个例子可以是这样的: 在此处输入图像描述

在此处输入图像描述

Only for finding an exercice I used 500mb...只是为了找到一个练习,我使用了 500mb...

Here are a few ways I can think of to optimize this:以下是我可以想到的几种优化方法:

  1. Use pagination and fetch more results as user scrolls down or actually separate it by using pages.使用分页并在用户向下滚动时获取更多结果或使用页面实际分隔它。 You can read more on how to implement pagination in Prisma here .您可以在此处阅读有关如何在 Prisma 中实现分页的更多信息。
  2. Add debounce to your search term so it doesn't actually fire on every single keystroke, you could use something like useDebounce .将 debounce 添加到您的搜索词中,这样它实际上不会在每次击键时触发,您可以使用类似useDebounce的东西。
  3. Use React.memo to prevent the list from being re-rendered every time some state changes, only re-render it when the actual list changes.使用React.memo来防止每次 state 更改时重新呈现列表,只有在实际列表更改时才重新呈现它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我如何遍历对象数组,为每个 object 调用 API,然后将响应设置为每个 object 中的值 - How can I iterate through an array of objects, make an API call for each object, then set the response as a value in each object 数千个对象会损害性能吗 - Can thousands of objects hurt performance React / Redux:需要帮助来渲染API响应 - React/Redux: Need help render API Response 使用FOR循环为API调用创建每个响应的文件 - Creating a file for each response from an API call with a FOR loop monit可以测试节点API调用的响应吗? - Can monit test for a response from a node API call? 如何通过快递请求 API 响应做出反应? - how can I pass request API response with express to react? 如何使用node.js在与未知数量的对象一样多的变量中将JSON响应的值存储到API调用中 - How to store the values of a JSON response to an API Call in as many variables as the (unknown) number of objects using node.js 使用API​​密钥的ExpressJS API调用 - ExpressJS API Call with API Key React JS / Node JS:从获取 API 响应中映射数组与内部对象的问题 - React JS / Node JS : Problem mapping array with objects inside from fetch API response 反应和 MySQL。 得到警告:列表中的每个孩子都应该有一个唯一的“关键”道具 - React and MySQL. got Warning: Each child in a list should have a unique “key” prop
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM