Check out a free preview of the full Client-Side GraphQL with React, v2 course
The "Using Mutations in React" Lesson is part of the full, Client-Side GraphQL with React, v2 course featured in this preview video. Here's what you'd learn in this lesson:
Scott demonstrates how to implement sign-up and sign-in functionality using GraphQL mutations. He creates the mutations and uses the `useMutation` hook to handle the mutations in the component. Scott also shows how to handle the response from the server and perform actions such as setting the token in local storage and redirecting the user to the homepage.
Transcript from the "Using Mutations in React" Lesson
[00:00:00]
>> Scott Moss: So I'm gonna go into my signup file. I pretty much copied and pasted the whole file here, but obviously if you go look at the file, it's it's all there. Really, the only thing that we're gonna be changing here is this handle signup. Where we actually use the mutation and sign up, so let's go do that.
[00:00:21]
I'm gonna go to the sign up page, which is gonna be app/(auth)/sign up. I'm gonna import use mutation, be sure you're importing from Oracle. I don't remember if I still have Apollo installed in here. And Apollo has a use mutation hook. Do not import the one from Apollo, it does not work the same.
[00:00:45]
It will break, I got stuck on that for an hour at one point. So yep, you gonna do that use mutation, and then we're gonna import our mutation that we created. So I'm gonna import our sign-up mutation from @gql/signupMutation, {SignupMutation}, like that. So we have our SignupMutation.
>> Scott Moss: I'm gonna come down here, and I'm going to say useMutation like this.
[00:01:19]
And I'm passing our SignupMutation. This is not going to make a mutation immediately when a component renders because you need variables. It needs to know when you want to do the mutation. Queries, on the other hand, will execute as soon as the component renders, by default you can turn that off.
[00:01:35]
But that's the same behavior as the React Query, SWR, it's like the same thing. Queries happen as soon as the component renders, mutations have to be triggered by some functions. So let's get that function. So in this Tupo here, we'll get the result, so this will be sign up result.
[00:01:50]
We probably won't use it, so I'm just putting a placeholder here. And then this other one is actually the function to call to signup, I'm just gonna call it signup. So we got that, and then basically, the strategy here is pretty simple. We call signup, remember, we have to pass in argument called input has to be the same name, and then its type is an object that has an email and password.
[00:02:11]
Well, that's what state has. State is an object with email and password. So we just pass in state, and then if we see that we get something back. We'll set the token in local storage and we're redirected to the homepage. So, let's do that. So I'll say result = await signup.
[00:02:40]
>> Scott Moss: Pass in my inputs and then pass in my state like that. And then if I say, if (results.data), remember, GraphQL never not does 200, you have to look at these properties. So for the most part, it'll just be these two. Data or error, if there's an error you'll get error, if there's data you'll get data.
[00:03:04]
You almost never get them both, these other ones don't really matter. We wanna check for data, so if there is data. I'm just gonna go a step further, I'm gonna say if there's data., and then what I can do is, if I go look at SignupMutation, it's always gonna be whatever this is called.
[00:03:20]
So there's gonna be data.createUser. It's gonna say that, so I'm gonna say if data.createUser. Then we're good. So I can say setToken, which is gonna be result.data.createUser.token and I know it's .token because it's rare. Let's call it token, it`s right there.
>> Scott Moss: I can actually rename this if I didn't wanna call it token, I could say something like this.
[00:03:54]
And that will actually rename it, that's a neat trick, If you wanted to call it thing and not token you could do that. That way the database functionality still works and it can map the fields to the database or whatever data source, but then the client gets renamed to this.
[00:04:08]
So you can do that if you want, I'm not doing that.
>> Scott Moss: So I'm gonna keep it like that.
>> Scott Moss: There we go that and then the last thing we wanna do is just a router.push(``/``) to the homepage like that. Everything else should already be set up, handle sign up should already be on form.
[00:04:31]
Submit, looks like it's good here, the set state's already working, that looks to be doing just fine. So, let's go see if we can sign up and let's see if we successfully were able to do this. So I'm gonna go my app here, make sure I gonna go /sign up like that.
[00:04:53]
I'm gonna sign up now, I'll pick a new email. I'm admin2@gmail.com and on password, okay go away and boom, we signed up [INAUDIBLE].
>> Scott Moss: Already missed it, I was gonna show the Network tab I already missed it. So if you did it right, you should be able to sign up here.
[00:05:17]
If you go look at the terminal, the output you can see we did a POST/api/graphql 200. It's always gonna say that on success. Even on failure, it's gonna say POST/api/graphql/200. So logs aren't even useful anymore for GraphQL because they're all gonna say 200. So you can forget about streaming your logs to some log provider because this is gonna say 200, you got to figure something else out.
[00:05:43]
>> Scott Moss: Any questions on sign up? Cool, then let's do the same thing right click for sign in, it should be pretty much the same thing, right? So, we go here, I'm just gonna get rid of this. I'm gonna say instead of create user, I wanna sign in and I'm gonna add the A token field, the input is actually the same, so I don't even have to change it.
[00:06:04]
It has the same AuthInput, just whatever you sign up with you also have to sign in with. So I made them exactly the same, so I don't even have to change that. Just gonna copy this sign in thing here,
>> Scott Moss: And I'm gonna go back to our gql folder.
[00:06:19]
I'm gonna make a new one, call signinMutation.
>> Scott Moss: And I'm gonna import gql, why am I doing that? Imports from @urql, gql and exports my SigninMutation. I use GQL and just that.
>> Scott Moss: If you don't have syntax highlighting for your GraphQL. Just go to the plugin store and type GraphQL.
[00:07:04]
There's probably so many of them at this point, but I think most editors kind of support it by default.
>> Scott Moss: Okay, got a signinMutation, we're gonna do the same thing. We're gonna go to our signin file and go to the page, and we're gonna do the exact same thing here.
[00:07:24]
So we're gonna import our useMutation like that, and we're going to import our signinMutation, like that. We're gonna make the mutation here with useMutation, passing our signinMutation will get the results here. We won't ever really use those, and we'll get the actual function I will call it signin.
[00:07:56]
>> Scott Moss: Like that.
>> Scott Moss: And then down here, we'll do this. data = await signin, takes the object with the input whose value is state.
>> Scott Moss: And if data.data, that's pretty redundant, .signin, I know it's called signin, cuz if I look at the mutation, it's called signin here. This was called, then it'd be data.data.thing.
[00:08:31]
But in this case it's data.data.sign in, cuz that's the name of the actual function here, or mutation, which is basically a function. So, if data.data.signin, we are good. Then I need to set the token, which should be data.data. My God, these pop ups like ads, [LAUGH] (data.data.signin.token), and then router.push(``/``).
[00:09:02]
Go to home.
>> Scott Moss: Everything else is wired up, should work just fine. So now if we go back to home, see if I can remember what I just signed in or signed up with, let's try to sign in. If I go to sign in, like I said, admin2@gmail.com.
[00:09:27]
And I think a password was just password. Yeah it was, so there we go. Sign in works, and again you can test all this out just by trying it out here, right? I can try sign in right now with that same credential, admin2@gmail.com. Password, if I run this, I just sign in.
[00:09:48]
Here's my JSON Web Token. If I wanna get my id in my email, here's my id. Here's my email, I can run it again. There it is, here's my id, there's my email. So this is a great place to test things out just to make sure things are working the way they should, figure out what queries you need, and then bring them into the app.
[00:10:07]
Just to quickly walk through them one more time to see what we did, so we can retain that a little bit and move forward. I'm gonna use our Apollo Studio here, and I'm I'm gonna close my sidebar there we go. And the comment I made about the variables, again, $ sign represents the argument name, you could pass it into any other function here in this case.
[00:10:40]
I pass it to the signup function. And then obviously we have our inputs here, which are the variables that you have to pass in, and then we get our output. So, nothing too complicated here, I think they did a really good job of mapping. I mean, that's the whole point of GraphQL is like mapping these fields to the actual data that you get back.
[00:11:00]
So, some of the things that I wanted to walk through before we hop into like the querying, which I think is gonna be useful for querying, are just some of these small. You might have seen me do them here or there, but some small transforms and things like that, and even some smaller things that you didn't know about that are quite powerful.
[00:11:17]
So for instance, if I wanted to rename one of these fields to something else. If I didn't want this to be called token, instead I wanted to be called jwt. I can rename the field like this with a colon, and if I rerun this, you'll see now in the output it's jwt and not token.
[00:11:40]
So why would I wanna do this? What is the purpose of this? Well, this is just something that benefits the client itself. In the case of this the GraphQL API is resolving for the field token. Maybe that's just, I mean, this is what the GraphQL schema says, is allowed.
[00:11:59]
It's a token, but if the front end doesn't want it to be token, then they can just remap it here. This just saves you from writing that code yourself. If you were gonna, do that transformation, I highly recommend using GraphQL as much as possible. So when you get the output from it, you can put it right on the screen, and that there isn't really a lot of manipulating and transforming that you have to do.
[00:12:21]
Before you put it on the screen, you should try to find a way to do that in GraphQL with some of these things what I just did here. There's also tons of other GraphQL plugins that allow you to manipulate and change things, to alter things. You can also make your own, it's a little more advanced, you kinda got to understand the AST a little bit when it comes to GraphQL, but you can definitely try to, that's the whole point of this.
[00:12:45]
If you're getting a result from GraphQL, just to map over it and pick the properties you really want and change the names. And you're not using GraphQL right, you need to do that here. Get the right names, get the right values, get the fields that you want in the query, and then put them on the screen, right?
[00:13:03]
So that's the use case, I'll try to figure out how to do that. It's just like database queries. You could query the database, and get all the things you need it, and run some code, and map over them and do this stuff. Or you could find the database query that does that for you on the database level, and get back get exactly what you want in a way that you want from the database.
[00:13:24]
So you wouldn't sort in the code, you would just ask the database to sort, right? So it's a very similar mindset. Try to get GraphQL to do the thing that you want, so you can go ahead and put it on the screen. So that's one trick there. The other thing is you can do inside of one operation like this or a function, you can do many queries or mutations, right?
[00:13:47]
So for instance, if I wanted to, let me see if I have one for all users. I don't. Okay, this will make more sense with a query. It doesn't really make sense with sign. You're not gonna sign in two people at once, so it doesn't really make sense for this example.
[00:14:05]
But you could come down here and say, you know what, I want to sign in again, so I could say again and I can say, signin and I could do this again. And I could sign in again and run this and give it an input and it'll run both of these at the same time simultaneously.
[00:14:25]
Again, this is really not a good use case for signing into people, but for a query it might make sense. Maybe you do a query to get these things and then unrelated, you do another query to get these things. So it's kinda batching, that's the best way I can describe it.
[00:14:39]
So you can do that in one operation as well. It's quite powerful and there's some more things here and there, but those things are quite advanced and they really depend on the client that you use. A lot of the stuff when it comes to front end GraphQL really depends on the actual client that you use and they aren't specific to the GraphQL spec.
[00:15:07]
So I'm refraining from showing those things. I know Urkel has some stuff that's specific to them. I know Apollo has some stuff that's specific to them. And I'm trying to refrain from using that, but for the most part you wanna stick to the GraphQL spec. And kinda do some stuff here, so just a quick note on a little bit of that.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops