I have this:
const BillsOverviewScreen = props => {
const { navigation } = props;
const [availableBills, setAvailableBills] = useState([]);
const bills = useSelector(state => state.bills.bills);
useEffect (() => {
setAvailableBills(bills);
}, [bills]);
const dispatch = useDispatch();
useEffect(() => {
dispatch(billsActions.loadBills());
}, [dispatch]);
React.useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<View style={{flexDirection:'row'}}>
<SortingMenu sortBills={sortBills} />
<FilterMenu />
</View>
),
});
}, [navigation]);
function sortBills(sortBy) {
switch (sortBy) {
case 'title': {
setAvailableBills(availableBills.sort((a, b) => a.title < b.title ? -1 : (a.title > b.title ? 1 : 0)))
break;
};
case 'dateExpiry_up': {
setAvailableBills(availableBills.sort((a,b) => new Date(b.dateExpiry) - new Date(a.dateExpiry)));
break;
};
case 'dateExpiry_down': {
setAvailableBills(availableBills.sort((a,b) => new Date(a.dateExpiry) - new Date(b.dateExpiry)));
break;
};
case 'dateCreated_up': {
setAvailableBills(availableBills.sort((a,b) => new Date(b.dateCreated) - new Date(a.dateCreated)));
break;
};
case 'dateCreated_down': {
setAvailableBills(availableBills.sort((a,b) => new Date(a.dateCreated) - new Date(b.dateCreated)));
break;
};
default:
return availableBills
}
}
Initially my state availableBills array gets filled as intended with the right data, but as soon as i use my sortBills function the array is empty. The weird thing is sometimes when i play around with it, its working. But when i reset my app its empty again. I really dont know what im doing wrong. tried different things but cant solve it.
sort does an in-place mutation, so you are mutating the state and not really ever updating it.
The
sort()method sorts the elements of an array in place and returns the sorted array.
Shallow copy the state first, then sort it, using .slice easily creates a copy inline. I suggest using a functional state update for this. The functional state update avoids stale state enclosures by updating from the previous state versus the value of availableBills closed over in callback scope.
setAvailableBills(availableBills =>
availableBills.slice().sort((a, b) =>
a.title < b.title ? -1 : (a.title > b.title ? 1 : 0)
));
Apply this pattern across all your cases.