1

I want to filter over an array using react hooks. It should be a fairly straight forward task, but I am assuming it is something to do with hooks being updated asynchronously, although this could be wrong.

I am fairly stumped, but have included a code sandbox and my code below:

const teams_data = [
  "tottenham",
  "arsenal",
  "man utd",
  "liverpool",
  "chelsea",
  "west ham"
];

function App() {
  const [teams, setTeams] = React.useState(teams_data);
  const [search, setSearch] = React.useState("");

  return (
    <div className="App">
      <input
        onChange={e => {
          const test = teams.filter(team => {
            return team.toLowerCase().includes(e.target.value.toLowerCase());
          });
          console.log("test: ", test);

          // uncomment line below and teams is logged as I want
          setTeams(test);
          setSearch(e.target.value);
        }}
        type="text"
        value={search}
      />
      {teams.map(team => (
        <p>{team}</p>
      ))}
    </div>
  );
}

3 Answers 3

5

You need to filter the original data :

  const test = teams_data.filter(team => {
    return team.toLowerCase().includes(e.target.value.toLowerCase());
  });

https://codesandbox.io/s/thirsty-austin-uqx8k

Sign up to request clarification or add additional context in comments.

2 Comments

just as a matter of interest why do you have to filter the original array?
feel free to answer here if you like - stackoverflow.com/questions/57754546/…
1

You just need to add another state for search results

    const [data , setData] = useState(teams);
    const [query, setQuery] = useState('')
    const[res , setRes] = useState([]);
    return (
      <div className="App container">
          <form onSubmit = {(e) => e.preventDefault()}>
              <input type = "search" className = "srh" placeholder = "search about..." 
              onChange = {(e) => {
                const test = data.filter(team => {
                  return (
                    team.toLowerCase().includes(e.target.value.toLowerCase())
                  )
                })
                setRes(test)
                if(e.target.value === '') setRes([])
              }}
              />
          </form>
          <div>
          {
            res.map((item , i) => (
            <p key = {i}>{item}</p>
            ))
          }
          </div>
      </div>
    );

Comments

0

I've made custom hook.

It receives the array as a first param
the search variable as a second
and the property you want to filter by

I hope it's helpfull

export function useSearch(array: any[], search: string, field: string) {
  const filteredArray = array.filter((entry) => {
    if (search === "") return entry;
    else if (
      entry[field].toLocaleLowerCase().includes(search.toLocaleLowerCase())
    )
      return entry;
  });
  return {
    filteredArray
  };
}

Them apply the filtered array to your map function

import { useSearch } from "./useSearch";
import { useState } from "react";

const array = [
  {
    id: 1,
    name: "Humberto Guenzo Yoshimoto"
  },
  {
    id: 2,
    name: "Diego Braga"
  },
  {
    id: 3,
    name: "Hudson Teixeira"
  },
  {
    id: 4,
    name: "Matheus Doimo"
  }
];

type FilteredArrayTypes = {
  id: number;
  name: string;
};

export default function App() {
  const [searchByFullName, setSearchByFullName] = useState("");

  const { filteredArray } = useSearch(array, searchByFullName, "name");

  return (
    <div className="App">
      <h1>Search list</h1>
      <input
        onChange={(e) => setSearchByFullName(e.target.value)}
        type="text"
        value={searchByFullName}
        placeholder="search"
      />
      {filteredArray.map((entry: FilteredArrayTypes) => {
        return (
          <ul>
            <li>{entry.name}</li>
          </ul>
        );
      })}
    </div>
  );
}

Here goes a sandbox with the code: here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.