skip to Main Content

I am using the Obytes Starter for a React Native app. It use React Query and React Query Kit for data fetching and React Hook Form and Zod for forms. This is my first time using React Query.

I’m struggling to understand how to make a React Query call on form submit. When using React Query’s refetch the call it either never makes the call or made it without the variables being passed. Since the form triggers a GET request I would like to avoid using a mutation query so the result can be cached.

use-price-query.ts

export const usePrice = createQuery<Response, Variables, AxiosError>({
  queryKey: ['price'],
  fetcher: (variables) => {
    return client.get('/items', {
        params: {
          item: variables.item,
        },
      })
      .then((response) => {
        return response.data;
      });
  },
});

PriceForm.tsx (imports, etc omitted)

const schema = z.object({
  type: z.string(),
  etc...
});

type FormType = z.infer<typeof schema>;

const PriceForm = () => {
  const { handleSubmit, control } = useForm<FormType>({
    resolver: zodResolver(schema),
  });

  const { data, refetch } = usePrice();

  const onSubmit = (formData: FormType) => {
    refetch(formData);
  };

  return (
    <View className="flex-1 justify-center p-4">
      <ControlledSelect />
      <ControlledInput />
      (more form fields here)
      <Button
        label="Get Shipping Rates"
        onPress={handleSubmit(onSubmit)}
        variant="default"
      />
    </View>
  );
};

2

Answers


    1. Destructure refetch from usePrice properly. The proper way const { data, refetch } = usePrice();
    2. Pass correct variable to the refetch. The correct usage is refetch({ variables: formData })
    Login or Signup to reply.
  1. It really depends on where you need the price to be available. If you only need the result within the onSubmit handler, you can use fetchQuery:

    const onSubmit = (formData: FormType) => {
      const data = queryClient.fetchQuery({
        queryKey: ['price', formData],
        queryFn : () => ...
      })
    };
    

    if you need the result available in the component, you want useQuery. However, useQuery is declarative, which means everything you use in the queryFn must be part of the query key. To get that, you must save the “applied values” from the submit handler somewhere, e.g. in local state:

    const [appliedData, setAppliedData] = useState()
    const priceQuery = useQuery({
      queryKey: ['price', appliedData],
      queryFn: () => ...,
      enabled: !!appliedData,
    })
    
    const onSubmit = (formData: FormType) => {
      setAppliedData(formData)
    };
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search