Domitrius Clark: We are utilizing the useQuery from react-query to search a list of names. What if I wanted to add those names to a favorites list? We can utilize useMutation from react-query to do this and the queryCache. Usually, you'll see useMutation used for put, patch, delete or post, but we're going to be using the queryCache to kind of mock that experience.
Let's define our useMutation function with our mutate function first, that we'll be naming addToFavorites. Then we'll call useMutation with its argument, which is the mutation function that we haven't defined yet, addCharacterOfFavorites.
Because we haven't defined yet addCharacterOfFavorites, we're going to see an error, so let's go ahead and define that function now. That function is going to take in a character variable that will be sending in to the mutate function of addToFavorites.
We're going to make use of the queryCache in a bit of a different way than you usually see it. We're going to use the setQueryData function, which will take two arguments, the first being the query key of favoriteCharacters and the second being a callback function that gives us access to the previous data in the same way that setState does.
First, let's make sure that the previous data isn't undefined so that we know that there's data inside of there. If it's not undefined, let's also make sure that the character that we're adding in doesn't already exist in that array.
Make use of the .some() array function and check the id of our current data against the incoming character.id. If it does match, we're just going to throw a new error letting our user know that they've already favorited that character.
If the character doesn't exist though, we can just return an array, spread the previous data into that array, and plot that character right into the array afterwards. Though if previous data is undefined, we can just return an array with that character inside of it.
Let's go into our JSX and start adding some divs so our view can be cleaned up a little bit as we add our new favorite section.
Let's make use of our addToFavorites function and add some fragments around our current return for our results.map so that we can add a button that onClick will fire our addToFavorites and send in the character as a variable.
When we search our characters, we're going to see that we have our + button, but it's not doing anything for the view. To fix that, let's define another useQuery for our favoriteCharacters. Since we already have a data variable, let's alias it to favoriteCharacters so that we don't get any conflicts. Then we'll call our useQuery with our query key of favoriteCharacters and our fetch function.
Next, we'll define our fetchFavorites() function, which is going to access to queryCache, but this time we'll use the getQueryData to access the queryCache's data and return it. QueryData's function argument will be the query key of favoriteCharacters so that we can return the array of favoriteCharacters within our queryCache.
Though we have access to the favoriteCharacters variable, we'll make sure it's not undefined. Then we'll do a map of the favoriteCharacters and just return the character.name for now. I'll just visualize the characters and the favoriteCharacters at the same time. We're just going to move the ReactQueryDevtools down and add display: "flex" with justifyContent: "space-between".
Let's do a character search, get our Ricks, and then see what happens when we add them. As you can see now, our Favorite Characters list is being filled.
I'm getting an error in our console for keys. Let's clean that up real quick and add some keys to our JSX to make sure that we don't see this error anymore. The console cleared. Now we can go ahead and search Ricks again and start adding some favorite characters to our list. Let's do a quick double-check on if we add the same character. You'll see we're getting our error.
Let's add another character from a different list. Let's check Mortys. As you can see, the query cache is being updated and populated with all the favorite characters between our searches.