3

I'm currently converting the logic in my mern (with typescript) project to use React/Tanstack query to learn this tool better.

I want to use useMutation to handle the post request logic from the details inputted in the form, in this login component but can't figure out how to do this. Any tips would be appreciated thanks. Below is the code from my login component



const Login = () => {
  const navigate = useNavigate();
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [errorMsg, setErrorMsg] = useState("");

  const [state, setState] = useContext(UserContext);

  const handleSubmit = async (e: { preventDefault: () => void }) => {
    e.preventDefault();
    let response;
    const { data: loginData } = await axios.post("http://localhost:5001/auth/login", {
      email,
      password,
    });
    response = loginData;

    if (response.errors.length) {
      return setErrorMsg(response.errors[0].msg);
    }

    setState({
      data: {
        id: response.data.user.id,
        email: response.data.user.email,
        stripeCustomerId: response.data.user.stripeCustomerId,
      },
      loading: false,
      error: null,
    });

    localStorage.setItem("token", response.data.token); 
    axios.defaults.headers.common["authorization"] = `Bearer ${response.data.token}`;

    navigate("/dashboard");
  };

  return (
    <div className="login-card">
      <div>
        <h3>Login</h3>
      </div>
      <form onSubmit={handleSubmit}>
        <div className="login-card-mb">
          <label>Email</label>
          <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
        </div>

        <div className="login-card-mb">
          <label>Password</label>
          <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
        </div>
        {errorMsg && <p>{errorMsg}</p>}
        <button type="submit">Submit</button>
      </form>
    </div>
  );
};

1 Answer 1

7

After setting up your project to use React Query ( Check the docs if you have not). You want to extract your api call to a separate function that takes an object. This object will hold the values you would like to post.

const Login = (dataToPost) => {
  let res = await axios.post('url', dataToPost)
  return res.data
}

Now that you have that, you can import useMutation from React Query. Once imported you can now use the hook. UseQuery, useMutation both contain a data variable so no need to create state for the data returned from your endpoint. In this example, I'm deconstructing the data and loading state. But most importantly the mutate function. Which allows you to fire off your api call. We add our api call to the hook. I'm renaming the mutate function to doLogin. It's a habit

const {data,isLoading,mutate:doLogin} = useMutation(Login)

Finally we can just call mutate(objectWithValues) wherever you want in your code. The data will initially be null and isLoading will be true once called. To tie it all together. Your handleSubmit could look as follows

const handleSubmit = () => {
  e.preventDefault();
  doLogin({email,password})
}

You also have the option of running functions on a success or error of the mutation

const {data,isLoading,mutate: doLogin} = 
useMutation(Login, {
  onError: (err) => console.log("The error",err),
  onSuccess:(someStuff)=>console.log("The data being returned",someStuff)
})
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks very much for the effort into explaining this! I've managed to get where i want now with the info provided
just wanted to leave a link to this great article as in combination with this post it helped me solve my similar problem as well. main takeaway is that you have to make an object of the data! tkdodo.eu/blog/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.