I was making a search bar component that modifies an array and then a mapping function that displays the resulted array it as the page results, the problem is that the page is delaying to update, in other words when I type a character in the search bar nothing changes but when I add another character the results are being updated with the first character input only and the.
I was using a hook state to hold the value of the search input and then using a filter function to update the array, finally I used a mapping function to display the modified array data as card components. As I said the problem is the delay that the website takes to update the array and it seams that the problem is with the state hook I uses but I couldn't solve that problem.
I also reuse the filtered array to display search suggetions
Here is app.js
import React, { useState } from "react";
import ReactDOM from "react-dom/client";
import Card from "./components/Card";
import resourcesData from "./resourcesData";
import { type } from "@testing-library/user-event/dist/type";
function App() {
const [filteredList, setFilteredList] = useState(resourcesData);
const [searchTerm, setSearchTerm] = useState("");
const changeInput = (event) => {
setSearchTerm(event);
};
function handleSearchTerm(event) {
setSearchTerm(event.target.value);
var updatedList = [...resourcesData];
updatedList = updatedList.filter((val) => {
if (searchTerm === "") return val;
else if (
val.title.toLocaleLowerCase().includes(searchTerm.toLocaleLowerCase())
) {
return val;
} else if (
val.thematicArea
.toLocaleLowerCase()
.includes(searchTerm.toLocaleLowerCase())
) {
return val;
}
});
setFilteredList(updatedList);
}
return (
<div className="App">
<input
type="text"
value={searchTerm}
onChange={handleSearchTerm}
className="input"
></input>
<div className="dropdown">
{filteredList.slice(0, 10).map((item) => (
<div
onClick={() => changeInput(item.title)}
className="dropdown-row"
key={item.title}
>
{item.title}
</div>
))}
</div>
<div className="cards">
{filteredList.map((value, index) => (
<Card
resourceURL={value.link}
thumbnailURL=""
title={value.title}
subtitle=""
date={value.date}
description=""
cost=""
cardkeywords={
value.cost === "free"
? [
value.level,
value.language,
value.type,
value.thematicArea,
value.cost,
]
: [
value.level,
value.language,
value.type,
...value.thematicArea.split(","),
]
}
key={index}
/>
))}
</div>
</div>
);
}
export default App;
CodePudding user response:
In the function handleSearchTerm
you use setSearchTerm(event.target.value);
and after you are using searchTerm
which updates asynchronously.
Use in this function event.target.value
.
function handleSearchTerm(event) {
const newValue = event.target.value;
setSearchTerm(newValue);
var updatedList = [...resourcesData];
updatedList = updatedList.filter((val) => {
if (newValue === "") return val;
else if (
val.title.toLocaleLowerCase().includes(newValue.toLocaleLowerCase())
) {
return val;
} else if (
val.thematicArea
.toLocaleLowerCase()
.includes(newValue.toLocaleLowerCase())
) {
return val;
}
});
setFilteredList(updatedList);
}