skip to Main Content

I have a search bar component. I would like to know how I can refactor the below code such that I can include html markup to display if there is no match. Right now the markup displays if there is a match or nothing displays if its blank.

I was getting errors when separating out the filter and map function.

return (
<div>
<input placeholder="Search Book Title" onChange={handleChange} />
        {
        bookList.filter(book => {
            let isMatched = (book.title.toLowerCase().includes(query.toLowerCase()));
    
            if (query === '') {
                return ;
            } else if (isMatched) {
                return book;
            }
        }).map((book, index) => (
            <div>           
            This is the book   
            </div>
        ))
        }
    </div>
)
};

I was getting errors when separating out the filter and map function.

2

Answers


  1. Do the filter first and assign the result to a variable. Check if the .length is zero, if it is return your no books found markup. Otherwise return your books that were found list. For example

    function getFilteredBooks() {
      let filteredBooks = bookList.filter(book => 
        book.title.toLowerCase().includes(query.toLowerCase())
      );
    
      if (filteredBooks.length === 0) {
        return (<div>No books</div>);
      } else {
        return books.map(book => <div>{{book.title}}</div>);
      }
    }
    
    // ... other code
    
    return (<div> <input placeholder="Search Book Title" onChange={handleChange} />{{getFilteredBooks()}}</div>)
    
    Login or Signup to reply.
  2. I would recommend assigning the result of the filtered books to a variable and then use it in your rendered result –

    const filteredBooks = bookList.filter(book => {
      return query != ""
        && book.title.toLowerCase.includes(query.toLowerCase())
    })
          
    return (
      <div>
        <input placeholder="Search Book Title" onChange={handleChange} />
        { filteredBooks.length == 0
        ? <p>No matching books</p>
        : filteredBook.map((book, index) => (
            <div key={index}>           
              This is the book   
            </div>
          ))
        }
      </div>
    )
    

    If the filter is an expensive computation, you should useMemo

    const filteredBooks = useMemo(() => (
      bookList.filter(book => (
        query != ""
          && book.title.toLowerCase.includes(query.toLowerCase())
          && someExpensiveCondition(query) // <-
      ))
    ), [bookList, query])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search