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.