0

I am using react-query, and there is a useCallback function dependent on some data from useQuery, but when I call useQuery's refetch funciton, the data in useCallback not update. I have done a test in useEffect, and the data in useEffect has updated.

useCallback

const updateCurrentActiveTemplate = useCallback(
    (type: string) => {
      console.log(templatesListQuery.data);
    },
    [templatesListQuery.data]
  );

useEffect

useEffect(() => {
    console.log(templatesListQuery.data, 'effect');
  }, [templatesListQuery.data]);

the refetch part

const handleTemplateDataSubmit = () => {
 await templatesListQuery.refetch();
 updateCurrentActiveTemplate(currentBusinessType);
}

When I click the submit button I will call the handleTemplateDataSubmit method.

When I call useQuery's refetch function, the two logs are all executed, but the data in useCallback and useEffect are different, data in useCallback is the stale data and data in useEffect is updated, why is that.

ChenLee
  • 1,371
  • 3
  • 15
  • 33
  • Could you show how is the updateCurrentActiveTemplate called? Does the data change with every request? What happens if you refetch multiple times? – yjay Dec 17 '22 at 03:05
  • @yjay I have added to the question content. – ChenLee Dec 17 '22 at 03:11
  • "*the data in useCallback and useEffect are different*" - yes of course. The effect is running because the state has been updated, with the new values. The callback however that you're calling after the `await` statement is still the same callback from when you pressed the button, with the old state. – Bergi Dec 17 '22 at 03:49

1 Answers1

0

When you create handleTemplateDataSubmit it binds the updateCurrentActiveTemplate creating a closure. When you call it, it still has the reference to the same function. Next handleTemplateDataSubmit, created on the next rerender of the component will bind the updated version of updateCurrentActiveTemplate which in turn will bind the new data.

useEffect is called after the component rerenders and so the function that is passed to it binds new data.

You can call updateCurrentActiveTemplate inside useEffect it should work. You could also, for testing purposes add another button which call the updateCurrentActiveTemplate and then press first submit and then the second button. Second button will have the new updateCurrentActiveTemplate function.

Edit

The refetch function should return the updated results. It's probably the cleanest solution.

yjay
  • 942
  • 4
  • 11