5

I have been trying to learn React-query but can't seem to trigger requests with my onSubmit event. Right now the code is sending the request with "washington" as the default parameter and printing it to the screen, and a new request also triggers with the onBlur event, and fetch the data if the city typed is valid.

The thing is that wish I could move this logic to the submit() function, treat the data on the input and only if the data is valid, proceed to make the request. This is the stackblitz where I reproduced the problem with a free apiKey: StackBlitz

This is the code:

import React, { useState } from 'react';
import { useQuery } from 'react-query';
import axios from 'axios';

const Fetch = async city => {
  let apiKey = '91b5ff77e9e7d1985a6c80bbbb3b2034';
  const { data } = await axios.get(
    `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey}&units=metric`
  );
  return data;
};

const Weather = () => {
  const [city, setCity] = useState('washington');
  const { data, error } = useQuery(['temperature', city], () => Fetch(city));

  const submit = () => {};

  return (
    <div>
      <form onSubmit={submit}>
        <input onBlur={e => setCity(e.target.value)} type="text" />
        <button type="submit">send</button>
      </form>
      {!data ? null : <div>{data.main.temp}</div>}
    </div>
  );
};

export default Weather;

2 Answers 2

6

You can also call setCity in the onSubmit event of the form, as the onSubmit event gets the complete submitted form in the submit event:

<form
  onSubmit={(event) => {
    event.preventDefault();
    const city = new FormData(event.currentTarget).get("city");
    // do validation here
    if (isValid(city)) {
      setCity(city)
    }
>
  <input name="city" type="text" />
  <button type="submit">send</button>
</form>

make sure to give your input a name so that you can grab it from the form submit event.

Sign up to request clarification or add additional context in comments.

Comments

1

You can use useMutation hooks. As what the documentation said mutations are typically used to create/update/delete data or perform server side-effects. For this purpose, React Query exports a useMutation hook.. This hooks will return an object that gives you a mutation function that you can use to trigger request based on user interactions.

const { mutate: renamedMutationFunction } = useMutation(newTodo => axios.post('/todos', newTodo)).

Then somewhere in your code, you can do:

const handleClick = () => { renamedMutationFunction(); //invoking the mutation }

EDIT

see @TkDodo answer for better solution. You can basically just re-set the city, and react-query will automatically refetch the data.

2 Comments

useMutation is not the way to go here. useMutation is for mutations (create, update, delete) because they are imperative. Furthermore, they don't create entries in the cache, you can't re-use the data in multiple components. Basically, you have no state management, no refetches and none of the goodies of react-query if you useMutation for GET requests.
@TkDodo You're right. I'm not fully aware about the question.

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.