Let's start by changing that star
icon based on whether this currently is a favorite or not,
I want to have that filled star only if it is a favorite and an empty star if it's not.
So in the end in the meal detail screen, we need to swap that icon which we're rendering here based
on the favorite status of this meal we loaded here. Now again, the
problem here is we can find out whether that meal is a favorite or not in a very easy way in the component
function but not really in the navigation options.
So again, we'll need params to communicate between these two but overall, that's not too difficult.
What I want to do here is I want to get my favorite meals with the help of use selector in the meal
detail screen component function with the help of state and then state.meals.favorite meals,
so I want to get all my favorite meals and now I simply want to check if that meal is part of the favorite
meals
and actually we can therefore refine this and even name this current meal is favorite and in the selector not just
return the favorite meals but add a bit more logic in there and simply add a check where we call some
which is also a built-in method which returns true if the condition which we're about to specify is
true for at least one item in that array and there, I check for every meal that's in there, if the meal
ID is equal to the meal ID I retrieve here and hence I have to swap lines.
So here, I get the mealId of the meal where we're loading on the detail screen and then I check my
favorite meals, if that meal ID is part of them which would mean that this meal is part of our favorites.
So with that, we have this current meal is favorite information, now we need to pass it to the navigation
options and again, we can do this with use effect, maybe down there. Just as before, provide a function
here in an array of dependencies, in the function here I'll set props navigation set params to merge
more data into my params and that is maybe the is fav param, name is up to you, which holds the current
meal is favorite value so that value which we just derived and now a dependency of that function, of
that use effect call I mean is of course current meal is favorite, when that changes, I want to forward
the new information to the params and therefore to the header, otherwise this effect shouldn't rerun.
So now back in the navigation options, we can retrieve that information here, is favorite can be retrieved
from navigationData.navigation with the help of get param and there I name
this is fav, here it is,
so that's the name by which we can retrieve it.
Now we have the is favorite information in the header and we can now use this to render a different icon
here.
So instead of always rendering iOS star, I'll have a dynamic expression here and I'll check if is
favorite is true,
if it is, then I want to use iOS star which is this field star,
if it's not,
I'll render iOS star outline and
that will be an empty star.
With that, we hopefully have a set up that works as expected.
If I go to the spaghetti,
now this is an empty star and if I click this,
it's a filled star and it's part of the favorites.
If I then go to the detail screen here, you see it takes a bit until the star is filled out here as well, we'll
have to fix this. If I now click it here and we go back to meals, there it also updated and that's the
magic of Redux, it updates one part of the application if something related changes in another part,
that's exactly how it should behave here. So that generally works,
the only thing that wasn't too beautiful is that this star here initially is empty and only gets filled
out after this is loaded, so we can fix that
but other than that, this is working as it should. Now to fix this initially empty star, again
we can use a workaround
I explained earlier for that initial header data.
We don't want to wait for the first render to finish,
instead we should pass this initial data into this component when we navigate to it.
Hence it's time for the meal list again where we have this navigation action to also forward
this is fav key already, so this key which I tried to extract here in the meal detail screen down there,
get param is fav. I want to pass the current value when we load this component, when we load this screen
here from inside the meal list which is the component which triggers that navigation to meal detail
and of course there,
itemData.item is a single meal but that doesn't hold information about whether that's part of our favorites
or not
but of course we can find out whether that's the case or not. In the meal list,
we can also tap into the Redux store, not just from the screen components.
So here I can also use use selector from React Redux like this and then in my component here, I can get
my favorite meals with the help of use selector where I get my state and then return state.meals
dot favorite meals to get all my favorite meals
and now when we render a single meal item, we can use that to find out whether that meal item is part
of our favorites. By the way,
you can't use use selector in there,
that would not be a valid usage because you must use React hooks only on the root level of your component
function, not in nested functions or nested if blocks or anything like that,
so using use selector in here is not allowed
but we can use our favorite meals in there of course and therefore here, we can find out whether this
is a favorite by simply checking the favorite meals and looking for the meal where its ID matches
the
itemData.item.id,
so the ID of the meal we're currently rendering. Therefore is favorite will hold the item we found
there,
alternatively we use some here which is a built-in Javascript method that will return true if any item
in favorite meals matches this condition.
So if is favorite is true, we know this item is a favorite and therefore we can use is favorite as a value
for is fav which we pass as an initial param to the meal detail screen
and now this flickering star which initially is empty should be gone.
Now if I mark this as a favorite here and I leave this and I come back, it's filled out right from the
start,
also on the favorite screen of course. So that's that,
this is how we can work with favorites,
let's now make sure we show some dummy text here on the favorite screen in case we got no data to display
otherwise and thereafter,
let's take care about our filters.