Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

refetch in reactQuery is not return the data

I am using reactQuery in my react application. I need to call one get API in button click. for that i am using refetch option in reactQuery. API call is working fine but my response data is coming undefined. I checked in browser network there i can see the response.

My API call using reactQuery

const { data: roles, refetch: roleRefetch } = useQuery('getRoles', () => api.getRoles('ID_234'), { enabled: false });

My click event const handleAdd = (e) => { roleRefetch(); console.log(roles) }

My action call using axios

export const getRoles = (name) => axios.get(roles/list?sa_id=${name}, { headers: setHeader }).then(res => res);


1 Answers

const handleAdd = (e) => { roleRefetch(); console.log(roles) }

this not how react works, and it's not react-query specific. calling a function that updates some state will not have your state be available in the next line. It will make it available in the next render cycle. Conceptually, you want this to work, which cannot with how react is designed:

const [state, setState] = React.useState(0)

<button onClick={() => {
  setState(1)
  console.log(state)
}}

here, the log statement will log 0, not 1, because the update doesn't happen immediately, and this is totally expected.

With react-query, what you can do is await the refetch, because its async, and it will give you the result back:

const handleAdd = async (e) => {
  const { data } = await roleRefetch();
  console.log(data)
}

or, depending on what you actually want to do, you can:

  • use data in the render function to render something - it will always be up-to-date.
  • use theonSuccess callback of useQuery to trigger side-effects whenever data is fetched
  • spawn a useEffect in the render function that does the logging:
const { data: roles, refetch: roleRefetch } = useQuery('getRoles', () => api.getRoles('ID_234'), { enabled: false });

React.useEffect(() => {
  console.log(roles)
}, [roles])

on a more general note, I think disabling a query and then calling refetch on a button click is very likely not idiomatic react-query. Usually, you have some local state that drives the query. in your case, that's likely the id. Dependencies of the query should go to the queryKey, and react-query will trigger a refetch automatically when the key changes. This will also give you caching by id. You can use enabled to defer querying when your dependencies are not yet ready. Here's what I would likely do:

const [id, setId] = React.useState(undefined)
const { data: roles } = useQuery(['getRoles', id], () => api.getRoles(id), { enabled: !!id });

const handleAdd = (e) => { setId('ID_234') }

of course, id doesn't have to come from local state - it could be some other form of client state as well, e.g. a more global one.

like image 135
TkDodo Avatar answered Aug 03 '26 04:08

TkDodo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!