I'm working on react table project, and can be searched and filtered by name and email both. The problem is Whenever I input a value it gets the previous state first, not the updated real-time value. Why is it and how to solve that? Thank You!
const URL = "https://jsonplaceholder.typicode.com/users";
function App() {
const [data, setData] = useState([]);
const [searchInput, setSearchInput] = useState("");
const [filteredResults, setFilteredResults] = useState([]);
const getData = async () => {
const response = await axios.get(URL);
setData(response.data);
};
useEffect(() => {
getData()
}, []);
Filtering By Name
const nameFilter = (e) => {
if (e.target.value !== "") {
setSearchInput(e.target.value);
const results = data.filter((user) => {
return user.name.toLowerCase().includes(searchInput.toLowerCase());
});
setFilteredResults(results);
} else {
setFilteredResults(data);
}
};
Filtering by Email
const emailFilter = (e) => {
if (e.target.value !== "") {
setSearchInput(e.target.value);
const results = data.filter((user) => {
return user.email.toLowerCase().includes(searchInput.toLowerCase());
});
setFilteredResults(results);
} else {
setFilteredResults(data);
}
};
Table Header
const renderHeader = () => {
let headerElement = ["id", "name", "email", "Company Name", "Zipcode"];
return headerElement.map((key, index) => {
return <th key={index}>{key.toUpperCase()}</th>;
});
};
Table Body
const renderBody = () => {
return (
<>{
searchInput ? (
filteredResults.map(({ id, name, email, company, address }) => {
return (
<tr key={id}>
<td>{id}</td>
<td>{name}</td>
<td>{email}</td>
<td>{company.name}</td>
<td>{address.zipcode}</td>
</tr>
);
})
) :
data.map(({ id, name, email, company, address }) => {
return (
<tr key={id}>
<td>{id}</td>
<td>{name}</td>
<td>{email}</td>
<td>{company.name}</td>
<td>{address.zipcode}</td>
</tr>
);
})}
</>
);
};
return (
<>
<h1 id="title">React Table</h1>
{!data.length ? (
<h2>Loading...</h2>
) : (
<div>
<span>
<input
type="search"
onChange={nameFilter}
className="input"
placeholder="Search by Name"
/>
<input
type="search"
onChange={emailFilter}
className="input"
placeholder="Search by Email"
/>
</span>
<table id="employee">
<thead>
<tr>{renderHeader()}</tr>
</thead>
<tbody>{renderBody()}</tbody>
</table>
</div>
)}
</>
);
}
export default App;