so i have 2 redux state and selectors that is working well. but i want to call the second selector (get the detail list based on category.id) inside map() loop. how can i do that?
const Dashboard = () => {
const [data, setData] = useState([]);
const categories = useSelector(viewFinalCategories);
// categories is loaded well
const createFinalData = () => {
const finalData = categories.map((category) => {
return {
title: category.label,
category: category,
data: useSelector(viewInventoriesByCategory(category.id)), // <- error hook cannot called here..
};
});
setData(finalData);
};
useEffect(() => {
createFinalData();
}, [categories]);
return (
// SectionList of RN here...
)
CodePudding user response:
Since it violates the hook rule, you can't call useSelector
inside a function.
the solution is to get the data in the component level and do the filtering inside the function
const {inventories} = useSelector(state => state)
const createFinalData = () => {
const finalData = categories.map((category) => {
return {
title: category.label,
category: category,
data: inventories.filter((item) => item.idCategory === idCategory)
};
});
setData(finalData);
};
CodePudding user response:
useSelector
is a hook and it has to follow hook rules, one of them is it can't be used inside a loop. Instaed, you need move all this logic from component to yet another selector. I would use createSelector
from reselect
in this case since you can combine selecting categories into newly created selectFinalData
:
import { createSelector } from 'reselect'
const selectFinalData = () =>
createSelector(
viewFinalCategories,
(state, categories) => categories.map((category) => ({
title: category.label,
category: category,
data: viewInventoriesByCategory(category.id)),
})
)
)
and use it in component :
const finalData = useSelector(selectFinalData())
setData(finalData);