I want to filter through a list of items and display the items according to my filtered term.
My list of items
const [persons, setPersons] = useState([
{ name: 'Arton Senna', tel: '9900000000' },
{ name: 'Ada Lovelace', tel: '39-44-5323523' },
{ name: 'Dan Abramov', tel: '12-43-234345' },
{ name: 'Mary Poppendieck', tel: '39-23-6423122' }
])
I have a input element that is a search field
<div>
<label htmlFor='filter'>Filter phonebook with</label>
<input type='text' name='filter_contacts' id='filter' onChange={filterText} />
</div>
The search field has an onchange handler
const filterText = (event) => {
return setFilter(event.target.value)
}
I am rendering the list items using .map
helper method
<ul>
{persons.map(person => <li key={person.tel}>{person.name} {person.tel}</li>)}
</ul>
My state objects are as follows
// persons
const [persons, setPersons] = useState([
{ name: 'Arton Senna', tel: '9900000000' },
{ name: 'Ada Lovelace', tel: '39-44-5323523' },
{ name: 'Dan Abramov', tel: '12-43-234345' },
{ name: 'Mary Poppendieck', tel: '39-23-6423122' }
])
// serachField
const [filter, setFilter] = useState('')
I want the ability to render my list according to what I type in my <input/>
element for search, so I did the following
<ul>
{persons
.filter(person => {
if (filter === '') {
return person
} else if (person.name.toLocaleLowerCase().includes(filter.toLowerCase())) {
return person
}})
.map(person => <li key={person.tel}>{person.name} {person.tel}</li>)}
</ul>
After doing this, eslint
gives me the following warning message
Array.prototype.filter() expects a value to be returned at the end of arrow function.eslintarray-callback-return
**Please help me understand this issue and how can I …**
- Use another approach here, to do what I want with filtering and rendering my list
- What is the problem with the way I’m doing it? (the code still works properly, but that warning message is annoying me)
- What is a succinct way to do the same task
@Quentin
I did the following refactor
{
filter
// truthy
? persons.filter(person => person.name.toLowerCase().includes(filter.toLowerCase())).map(person => <li key={person.tel}>{person.name} {person.tel}</li>)
// falsy
: persons.map(person => <li key={person.tel}>{person.name} {person.tel}</li>)
}
Advertisement
Answer
What is the problem with the way I’m doing it?
ESLint wants you to explicitly return something: always.
If the code gets to the end of the function, it implicitly returns undefined
. ESlint expects you to be explicit.
person => {
if (filter === '') {
return person
} else if (person.name.toLocaleLowerCase().includes(filter.toLowerCase())) {
return person
}
return false; // Explicit
}
What is a succinct way to do the same task
person => (filter === '' || person.name.toLocaleLowerCase().includes(filter.toLowerCase()).toLowerCase())
… should do the trick.