I am currently pulling data from an API that gives random user data like name, age, email, etc ... I have setup a searchbar component and I map over the array but it returns all my names without waiting on a userInput. I am passing my state as props deconstructed as shown below. I also get no errors on my terminal and my console except for a key prop that should not be an issue for this.
import React, { useState } from "react";
const SearchBar = ({userData}) => {
const [searchInput, setSearchInput] = useState("")
const handleChange = (e) => {
e.preventDefault();
setSearchInput(e.target.value);
}
if (searchInput.length > 0) {
userData.filter((data) => {
return data.name.first.match(searchInput);
})
}
return (
<div>
<input
type="text"
placeholder="Search"
onChange={handleChange}
value={searchInput} />
<table>
<tbody>
<tr>
<th>First name</th>
<th>Last name</th>
</tr>
{userData.map((user, index) => {
return (
<tr>
<td>{user.name.first}</td>
<td>{user.name.last}</td>
</tr>
)
})}
</tbody>
</table>
</div>
);
};
export default SearchBar;
CodePudding user response:
The code isn't doing anything with the filtered result. Remember that Array.prototype.filter
returns a new array. In the case of your code I often recommend just filtering the array inline prior to mapping the elements to JSX. Don't forget to add a React key to the mapped JSX!
Example:
const SearchBar = ({ userData = [] }) => {
const [searchInput, setSearchInput] = useState("");
const handleChange = (e) => {
e.preventDefault();
setSearchInput(e.target.value.toLowerCase()); // sanitize to lower case
}
return (
<div>
<input
type="text"
placeholder="Search"
onChange={handleChange}
value={searchInput}
/>
<table>
<tbody>
<tr>
<th>First name</th>
<th>Last name</th>
</tr>
{userData
.filter(data => {
if (searchInput) {
return data.name.first.toLowerCase().match(searchInput);
}
// no filtering, return no elements
return false;
})
.map((user) => (
<tr key={user.name.first " " user.name.last}> // <-- React key!
<td>{user.name.first}</td>
<td>{user.name.last}</td>
</tr>
))
}
</tbody>
</table>
</div>
);
};
CodePudding user response:
You need to store the filtered results in another variable:
let filteredData=[];
if (searchInput.length > 0) {
filteredData = userData.filter((data) => {
return data.name.first.match(searchInput);
})
}
and then in you JSX use filteredData instead of userData
{ filteredData.map((user, index) => {
return (
<tr>
<td>{user.name.first}</td>
<td>{user.name.last}</td>
</tr>
)
})}