so, I have this function here
const [shopItems,setShopItems] = useState("");_
useEffect(()=> {
commerce.products.list().then((product) => {
setShopItems(product)
});
}, [])
function categorize(category) {
let categoryarray = []
if (shopItems!= "s") {
shopItems.data.forEach((el)=> {
for (let i =0; i < el.categories.length; i ) {
if (el.categories[i].slug == category) categoryarray.push(el)
}
})
}
return categoryarray;
}
the useEffect Hook was just for context, I'm mostly concerned about the categorize function. Is there anyway to optimize this since I have observed that my website scrolls very slowly, and I think this might be one of the culprits behind the slow scrolling speeds. Thanks in Advance!
CodePudding user response:
The only way I can see to optimise that code is to exit as soon as a match is found. (I prefer using a while
loop for this purpose).
shopItems.data.forEach(el => {
let idx = 0;
while (idx < el.categories.length) {
if (el.categories[idx].slug == category) {
categoryarray.push(el);
break;
} else {
idx ;
}
}
});
If you wanted something that looked slightly better (not mixing forEach
and for
, for example) you could use this: (no performance enhancements as far as I can see though)
shopItems.data.forEach(el => {
if (el.categories.map(({ slug }) => slug).includes(category)) categoryarray.push(el);
});
Or even use reduce
:
let categoryarray = shopItems.data.reduce((a, c) => {
if (c.categories.map(({ slug }) => slug).includes(category) return a.concat(c);
else return a;
}, []);
The first option is still the most performant as realistically it will run through the loop less times.
CodePudding user response:
You can use useMemo https://reactjs.org/docs/hooks-reference.html#usememo
useMemo works by having 2 parameters. A function and an array of dependencies, if any of the dependencies change it re-runs the provided function and stores the value, next render if the dependencies havent changed it just uses the previous value.
const categories = useMemo(() =>
let categoryarray = []
if (shopItems!= "s") {
shopItems.data.forEach((el)=> {
for (let i =0; i < el.categories.length; i ) {
if (el.categories[i].slug == category) categoryarray.push(el)
}
})
}
return categoryarray;
}, [shopItems.data, category])