简体   繁体   中英

Filtering out data React Native best practice

I need advice on where to perform data filtering to achieve best performance. Let's say I receive a big array of products from one endpoint of a remote API and product categories from another endpoint. I store them in Redux state and also persist to Realm database so that they are available for offline usage.

In my app, I have a Stack.Navigator that contains 2 screens: ProductCategories and ProductsList . When you press on a category it brings you to the screen with products that fall under that category . Currently, I perform the data filtering right inside my component, from my understanding it fires off every time the component is rendered and I suspect this approach slows down the app. So I was wondering if there is a better way of doing that? Maybe filter the data for each category in advance when the app is loading?

My code looks as follows:

const ProductCategories = (props) => {

const isFocused = useIsFocused();

useEffect(() => {
    if (isFocused) {
      setItems(props.productCategories);
    } 
  }, [isFocused]);

return ( 
 ...
 );
};

const mapStateToProps = (state) => ({
  productCategories: state.catalog.productCategories,
});
const ProductsList = (props) => {

const isFocused = useIsFocused();

const productsFilteredByCategory = props.products.filter((product) => {
    return product.category === id;
  });
  useEffect(() => {
    if (isFocused) {
      setItems(productsFilteredByCategory);
    } 
  }, [isFocused]);

return (
...
)


const mapStateToProps = (state) => ({
  products: state.catalog.products,
});


You have to normalize (you can see main principles here ) data in redux, to the next view:

// redux store
{
  categories: {
    1: { // id of category
      id: 1,
      title: 'some',
      products: [1, 2, 3] // ids of products
    },
    ...
  },
  products: {
    1: { // id of product
      id: 1,
      title: 'some product',
    },
    ...
  }
}

Then you can create few selectors which will be even without memoization work much faster then filter, because time of taking data from object by property is constant

const getCategory = (state, categoryId) => state.categories[categoryId]
const getProduct = (state, productId) => state.products[productId]

const getCategoryProducts = (state, categoryId) => {
  const category = getCategory(state, categoryId);

  if (!category) return [];

  return category.products.map((productId) => getProduct(state, productId))
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM