[英]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:
我完成了创建它,但我有一些问题:
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 能找到这些元素,它们就会呈现在屏幕上。
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:以下是我可以想到的几种优化方法:
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.