Home > OS >  React Search bar maps out every item instead of waiting for userInput
React Search bar maps out every item instead of waiting for userInput

Time:08-01

I am currently pulling data from an API that gives random user data like name, age, email, etc ... I have setup a searchbar component and I map over the array but it returns all my names without waiting on a userInput. I am passing my state as props deconstructed as shown below. I also get no errors on my terminal and my console except for a key prop that should not be an issue for this.

import React, { useState } from "react";

const SearchBar = ({userData}) => {
    const [searchInput, setSearchInput] = useState("")

    const handleChange = (e) => {
        e.preventDefault();
        setSearchInput(e.target.value);
    }

    if (searchInput.length > 0) {
        userData.filter((data) => {
            return data.name.first.match(searchInput);
        })
    }

  return (
    <div>
      <input
       type="text"
       placeholder="Search"
       onChange={handleChange}
       value={searchInput}  />

        <table>
            <tbody>
            <tr>
            <th>First name</th>
            <th>Last name</th>
            </tr>
            {userData.map((user, index) => {
                return (
                    <tr>
                    <td>{user.name.first}</td>
                    <td>{user.name.last}</td>
                </tr>
                )
                   
            })}
            </tbody>
        </table>

    </div>
  );
};

export default SearchBar;

This is what I see right now

CodePudding user response:

The code isn't doing anything with the filtered result. Remember that Array.prototype.filter returns a new array. In the case of your code I often recommend just filtering the array inline prior to mapping the elements to JSX. Don't forget to add a React key to the mapped JSX!

Example:

const SearchBar = ({ userData = [] }) => {
  const [searchInput, setSearchInput] = useState("");

  const handleChange = (e) => {
    e.preventDefault();
    setSearchInput(e.target.value.toLowerCase()); // sanitize to lower case
  }

  return (
    <div>
      <input
        type="text"
        placeholder="Search"
        onChange={handleChange}
        value={searchInput}
      />
      <table>
        <tbody>
          <tr>
            <th>First name</th>
            <th>Last name</th>
          </tr>
          {userData
            .filter(data => {
              if (searchInput) {
                return data.name.first.toLowerCase().match(searchInput);
              }
              // no filtering, return no elements
              return false;
            })
            .map((user) => (
              <tr key={user.name.first   " "   user.name.last}> // <-- React key!
                <td>{user.name.first}</td>
                <td>{user.name.last}</td>
              </tr>
            ))
          }
        </tbody>
      </table>
    </div>
  );
};

CodePudding user response:

You need to store the filtered results in another variable:

  let filteredData=[];
  if (searchInput.length > 0) {
    filteredData = userData.filter((data) => {
          return data.name.first.match(searchInput);
      })
  }

and then in you JSX use filteredData instead of userData

      { filteredData.map((user, index) => {
          return (
          <tr>
             <td>{user.name.first}</td>
             <td>{user.name.last}</td>
         </tr>
         )
      })}
  • Related