Home > Net >  React Filtering Approach
React Filtering Approach

Time:10-07

I have such data:

created: "2017-11-04T18:48:46.250Z"
episode: (51) ['https://rickandmortyapi.com/api/episode/1', 'https://rickandmortyapi.com/api/episode/2', 'https://rickandmortyapi.com/api/episode/3', 'https://rickandmortyapi.com/api/episode/4', 'https://rickandmortyapi.com/api/episode/5', 'https://rickandmortyapi.com/api/episode/6', 'https://rickandmortyapi.com/api/episode/7', 'https://rickandmortyapi.com/api/episode/8', 'https://rickandmortyapi.com/api/episode/9', 'https://rickandmortyapi.com/api/episode/10', 'https://rickandmortyapi.com/api/episode/11', 'https://rickandmortyapi.com/api/episode/12', 'https://rickandmortyapi.com/api/episode/13', 'https://rickandmortyapi.com/api/episode/14', 'https://rickandmortyapi.com/api/episode/15', 'https://rickandmortyapi.com/api/episode/16', 'https://rickandmortyapi.com/api/episode/17', 'https://rickandmortyapi.com/api/episode/18', 'https://rickandmortyapi.com/api/episode/19', 'https://rickandmortyapi.com/api/episode/20', 'https://rickandmortyapi.com/api/episode/21', 'https://rickandmortyapi.com/api/episode/22', 'https://rickandmortyapi.com/api/episode/23', 'https://rickandmortyapi.com/api/episode/24', 'https://rickandmortyapi.com/api/episode/25', 'https://rickandmortyapi.com/api/episode/26', 'https://rickandmortyapi.com/api/episode/27', 'https://rickandmortyapi.com/api/episode/28', 'https://rickandmortyapi.com/api/episode/29', 'https://rickandmortyapi.com/api/episode/30', 'https://rickandmortyapi.com/api/episode/31', 'https://rickandmortyapi.com/api/episode/32', 'https://rickandmortyapi.com/api/episode/33', 'https://rickandmortyapi.com/api/episode/34', 'https://rickandmortyapi.com/api/episode/35', 'https://rickandmortyapi.com/api/episode/36', 'https://rickandmortyapi.com/api/episode/37', 'https://rickandmortyapi.com/api/episode/38', 'https://rickandmortyapi.com/api/episode/39', 'https://rickandmortyapi.com/api/episode/40', 'https://rickandmortyapi.com/api/episode/41', 'https://rickandmortyapi.com/api/episode/42', 'https://rickandmortyapi.com/api/episode/43', 'https://rickandmortyapi.com/api/episode/44', 'https://rickandmortyapi.com/api/episode/45', 'https://rickandmortyapi.com/api/episode/46', 'https://rickandmortyapi.com/api/episode/47', 'https://rickandmortyapi.com/api/episode/48', 'https://rickandmortyapi.com/api/episode/49', 'https://rickandmortyapi.com/api/episode/50', 'https://rickandmortyapi.com/api/episode/51']
gender: "Male"
id:1
image:"https://rickandmortyapi.com/api/character/avatar/1.jpeg"
location: {name: 'Citadel of Ricks', url: 'https://rickandmortyapi.com/api/location/3'}
name:"Rick Sanchez"
origin: {name: 'Earth (C-137)', url: 'https://rickandmortyapi.com/api/location/1'}
species:"Human"
status:"Alive"
type:""
url:"https://rickandmortyapi.com/api/character/1"

And I have like 800 records like that have 3 filters where I can find name, status, gender

so I created:

useEffect(() => {
    if (name || gender || status) {
      setFilteredData(characters.filter((character) => character.name.includes(name)) && character.status === status && character.gender === gender)
    }
  }, [name, gender, status])

And it is fine only when I have 3 values of these filters, but how can I change it and not add let say gender filter here when the filter is empty? Because right now I have gender = '', status = '', name = '' as default filters and it doesn't find any records.

How can it be done?

CodePudding user response:

Since filteredData is a pure function of state, it shouldn't be state at all itself, but you should use useMemo instead.

Then, move your filtering logic into a separate pure function, and hook them up:

function characterMatchesFilter(character, name, gender, status) {
  if (name && !character.name.includes(name)) return false;
  if (gender && character.gender !== gender) return false;
  if (status && character.status !== status) return false;
  return true;
}

function RickAndMortyVerse() {
  const characters = []; // Your data here...
  const [name, setName] = useState(null);
  const [gender, setGender] = useState(null);
  const [status, setStatus] = useState(null);
  const filteredCharacters = React.useMemo(
    () => characters.filter((character) => characterMatchesFilter(character, name, gender, status)),
    [characters, name, gender, status],
  );
  // TODO: add UI to modify the filters.
  return (
    <>
      {filteredCharacters.map((c) => (
        <div key={c.name}>{c.name}</div>
      ))}
    </>
  );
}

CodePudding user response:

(character.name.includes(name)) || name === '') && (character.status === status || status === '') && (character.gender === gender || gender === '')

I would just adjust the filter callback to return true for each of your and statements if the filter is the empty string.

  • Related