Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to filter data in React?

I'm building a catalogue of restaurants in the country. The API returns an array of objects, each one consisting of fields such as restaurantName, restaurantLocation, restaurantPriceRange.

I want to create a filtering component, which will reduce the array of restaurants to a subset containing only those that match the search criteria. I also need to pass the filter values via the URL, for which I believe I should use a router.

I was thinking about storing the initial data set with useState hook and then using useReducer to store active filter selection and a subset of the filtered restaurant collection with only those matching the search criteria, but I feel like this is a clumsy solution, as effectively I would be duplicating a subset of the entire restaurant collection.

However, if I do not store the initial data set in a separate object using useState, all non-matches will be gone forever once the filters have been applied.

What would be the best way to achieve this?

DISCLAIMER: I know how to filter arrays in JavaScript and am fully aware of functions such as filter, map, sort, etc. This question is about the React ecosystem and what would be the cleanest, simplest and best way to structure my code in a React application. I know that I will still have to use Array.prototype.filter in my reducer when I write the code for it.

like image 716
goodpixels Avatar asked Nov 28 '25 03:11

goodpixels


1 Answers

You are asking for opinions so here is mine. React state (whether it’s useState or useReducer) should only be used for stateful values — the values which change and cause your rendered data to change. The filtered list of restaurants is not a stateful value. The filters are a stateful value, and the filtered list is derived from that state. The filtered list should be a const that you generate on each render. If there are other states or props in your component that change which do not effect the filtered list, you can use the useMemo hook to memoize the filtered list to prevent unnecessary recalculations.

Pseudo-code

import React, {useMemo} from “react”;
import {useLocation} from “react-router-dom”;

export const MyComponent = ({restaurants}) => {

   const location = useLocation();

   const filteredRestaurants = useMemo( () => {
       return restaurants.filter( /* some code */ );
   }, [location, restaurants] ); //dependency on location and restaurants 

   return (
      <Wrapper>
        <EditFiltersComponent />
        <List>
           {filteredRestaurants.map( restaurant => 
              <Restaurant {...restaurant} />
           )}
        </List>
      </Wrapper>
   )
}
like image 126
Linda Paiste Avatar answered Nov 30 '25 23:11

Linda Paiste



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!