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.