Maximilian: And of course we can do this with functions.
We can add a function
that's called the addFavoriteHandler() {} for example,
and a function that we could call removeFavoriteHandler()
and I will also add a helper function
which I'll name itemIsFavoriteHandler.
That's a function which will later help us determine
whether a given item is a favorite or not.
Now in the addFavoriteHandler item,
I expect to get my favoriteMeetup as a parameter.
And then in there,
I wanna set my user favorites to the old array
plus this new item.
Now for this,
we could use userFavorites.concat
and add the (favoriteMeetup);
Concat is like push but returns a new array,
and it's then this new array with that added Meetup
which we set as our new state.
But there is a gotcha.
We should not do it like this
even though it's typically will work.
When working with useState,
it is worth knowing that React actually does not process
state updates instantly
but it schedules them behind the scenes.
And it still then processes them very quickly
but not instantly necessarily.
Now because of that, when you update your state,
and your state updates depends on the latest state snapshot,
there is a scenario where the state snapshot
does not really reflect the latest state
because the last state update wasn't processed yet.
And because that is the case, there is an alternative form
of calling this state updating function
if you depend on that last state snapshot.
Instead of passing the new value as I did it a second ago,
you should pass a function to the state updating function.
And that function will be executed for you by React.
That function will then automatically
receive the previous state snapshot.
So the (prevUserFavorites) here,
and you should return the updated state here.
So in this case, (prevUserFavorites) where
we then concat the {favoriteMeetup}; we get as a parameter.
This will guarantee
that we always get the latest state snapshot here,
because React will execute these functions,
which we pass through the state updating functions
in the correct order.
So now, we have a guaranteed that we definitely work
on the latest state snapshot here,
and that's therefore the better way of updating your state,
if you depend on a previous version of that state.
And that's now how we could add a favorite item.
Now in removeFavoriteHandler,
we probably can expect a {meetupId}
which identifies the meetup that should be removed.
And then we can update userFavorites.
Again, with this state updating a function,
where we get the prevUserFavorites
and return a new state snapshot
because here again, we rely on that previous state.
And here we then wanna return prevUserFavorites.filter();
because filter returns a new array
where we can filter out items.
And I wanna filter out the item
where the meetupId matches this Id
we're getting as a parameter.
Filter is a built in method,
which takes a function as an argument
which executes for every item in this array,
and we get that item as a parameter then
and then we have to return true
if we wanna keep that item
or false if we wanna get rid of it in that new array
which has returned.
And here I wanna return true
if meetup.id !==meetupId I get as a parameter.
So, if it is equal,
we return false here because of this check,
and that means we drop the item where the Id is equal.
And that means that the returned array will be missing
the item which has this meetupId,
which is exactly what we need here,
since we want to remove that item.
And in itemIsFavoriteHandler,
I just want to return a response here,
I return a value,
and I want to check whether...
Let's say an item with a given Id is part of our favorites.
And for this, we don't need to update any state.
It's just a helper function
where I return userFavorites.some();
which is a nav built-in method
which exists in Vanilla JavaScript.
And some also wants a function as an argument
which executes for every item in this array,
and this function should return true or false.
And if at least one of the items in the array returns true
or false with that function,
some overall will return true or false.
And that allows us to find out
if some item in this array matches our condition here.
And the condition is that some meetup.id is == meetupId
we get as a parameter.
So we return true,
if we have a meetup with that Id in our user favorites.
Now we get these free functions for changing our context,
but at the moment these functions are never called anywhere.