What I want to do is create a Search functionality in my rudimentary React phonebook app. The initial data for the persons is stored in a db.json file in the project root.
This is the problematic code where after I type in something within an input field, the whole display for the list of persons goes blank:
import React, {useState} from 'react';
const Search = ({persons, setPersons}) => {
const [filter, setFilter] = useState('');
const handleFilterEntry = (event) => {
const value = event.target.value;
setFilter(value);
const filteredPersons = persons.filter( person => {
person.name.toLowerCase().includes(value.toLowerCase())
});
setPersons(filteredPersons);
console.log(value);
}
return (
<div>
Filter names with: <input value = {filter} onChange={handleFilterEntry}/>
</div>
)
}
export default Search;
And this is the updated code for the handleFilterEntry function that fixes the problem:
const handleFilterEntry = (event) => {
const value = event.target.value;
setFilter(value);
const filteredPersons = value
? persons.filter(
(person) =>
person.name.toLowerCase().includes(value.toLowerCase())
)
: persons;
setPersons(filteredPersons);
console.log(value);
};
I want to know why adding that conditional logic worked and solved the problem?
I also want to know that on backspacing certain characters from the input field, why does the list not revert back to show list of Persons with the backspaced letters.
Example:
There are names Joe and Jack in the list.
I type J, it filters down to Joe and Jack.
I type Jo, it filters down to Joe.
But I backspace to just J, it does not revert back to display both Joe and Jack in the list and still displays just Joe.
Any help would be appreciated, I’m a newbie. Thanks in advance!
2
Answers
part 1. Why does it show an empty list
You are not returning the check value in your filter function
person.name.toLowerCase().includes(value.toLowerCase())
this should be returned for filter to workpart 2. Why does backspace not work?
now initially your list is
[jim, joe]
on searching for
jo
it becomes[joe]
when you press backspace the array is still
[joe]
you have removed
jim
from that array so it will not appear in the list when you press backspaceIt’s not the conditional logic that fixed it, it’s the fact that your filter function is now returning a value. You started with this:
The above function has curly brackets marking out a function body, but it does not have a
return
statement. You then switched to this:The curly brackets are now gone. This means you’re using the shorthand version of an arrow function. In the shorthand syntax, javascript automatically assumes a
return
.That’s because you’ve deleted that data. Each time you type a letter, you shrink the array and set state.
.filter
is never going to increase the size of the array, so when you remove a letter, it will just keep the array the same size it already is.The fix is to not change
persons
; let that contain the full set of data. You’ll then calculate the filtered list from that, during rendering:You can improve the performance of this with useMemo so you only recalculate
filteredPersons
if something relevant has changed: