Refreshing data with useQuery when the argument is updated

I have been working on implementing pagination with react-query. Whenever the page changes, I update the page within the useEffect using setArrivals. However, I have noticed that the previous value of arrivals is always being sent as the argument for the getProductList function. To resolve this issue, I have resorted to sending a refetch() request inside a setTimeout, but this solution doesn't sit right with me. Can you please help me identify what I am doing wrong?

const HomePage = ({ newArrivals }) => {
  const [page, setPage] = useState(1);
  const [arrivals, setArrivals] = useState({ ...newArrivals, page: page });

  useEffect(() => {
    setArrivals((values) => {
      console.log({ page });
      return { ...values, page: page };
    });
    setTimeout(function () {
      newArrivalsQuery.refetch();
    }, 0);
  }, [page]);

  const newArrivalsQuery = useQuery(
    ['productListByNewArrivals'],
    () => getProductList(arrivals),
    {
      select: useCallback((data) => {
        return JSON.parse(data);
      }, []),
    }
  );

  return (
    <>
      <NewArrivals
        newArrivalsQuery={newArrivalsQuery}
        page={page}
        setPage={setPage}
      />
    </>
  );
};

export async function getServerSideProps(context) {
  const newArrivals = {
    sort: 'createdAt',
    order: 'desc',
  };

  try {
    const queryClient = new QueryClient();

    await queryClient.prefetchQuery('productListByNewArrivals', async () => {
      const newArrivalsResult = await listProduct(newArrivals);
      return JSON.stringify(newArrivalsResult);
    });

    return {
      props: {
        newArrivals: newArrivals,
        dehydratedState: dehydrate(queryClient),
      },
    };
  } catch (error) {
    console.log('error: ', error);
    if (error) {
      return {
        redirect: {
          destination: '/login',
          permanent: false,
        },
      };
    }
  }
}

Answer №1

To optimize your query function in react-query, it is best practice to include the dependencies of the function within the queryKey parameter. By doing this, react-query will automatically re-fetch data when the queryKey changes, eliminating the need to manually use useEffect and refetch. Here's an example:

const HomePage = ({ newArrivals }) => {
  const [page, setPage] = useState(1);
  const [arrivals, setArrivals] = useState({ ...newArrivals, page: page });

  const newArrivalsQuery = useQuery(
    ['productListByNewArrivals', arrivals],
    () => getProductList(arrivals),
    {
      select: useCallback((data) => {
        return JSON.parse(data);
      }, []),
    }
  );

In this setup, 'arrivals' are included in the queryKey used by getProductList, allowing react-query to handle automatic re-fetching. Simply calling setArrivals will trigger a re-fetch process.

It's worth noting that 'arrivals' may not necessarily be true state but rather derived state. To ensure proper synchronization with 'page', consider updating 'arrivals' inline with setPage:

  const [page, setPage] = useState(1);
  const arrivals = { ...newArrivals, page: page };

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Incorporate HTML into a webpage using JavaScript along with variables

So, I need to dynamically add and remove content to an HTML page with complex styling and data sets that will change based on the clicked element. An example scenario could be like this... <li class="foo"> <div class="slider" data-one="foo" d ...

Identify the transition of the parent element containing the <iframe> from a hidden state to a

Is there a way to identify when an iframe is shown after being hidden? HTML : <div style="display:none"> <iframe></iframe> </div> When the <div> is displayed using jQuery with $('div').show();, how can I determi ...

When I hover over div 1, I am attempting to conceal it and reveal div 2 in its place

I need help with a CSS issue involving hiding one div on mouse hover and showing another instead. I attempted to achieve this using pure CSS, but both divs end up hidden. Would jQuery be necessary for this task? Below is the CSS/HTML code I wrote: .r ...

Tips for concealing the angular component depending on a specific circumstance

I have developed a custom directive for validating input. It is designed to check the length of the input. If the length is zero, an error message will be displayed. However, I am facing difficulty in hiding the error message when the input is filled with ...

Is there a way to prevent an external script from making changes to an inline style?

There is a mysterious script running on a page that seems to be controlling the height of an inline style. The source of this script modifying the height property is unknown. <div class="vgca-iframe-wrapper wpfa-initialized" style="heigh ...

Is there a way to detect when the user closes a tab or browser in HTML?

I am currently developing a web application using the MVC architecture and I need to find a way to detect when a user closes their browser tab so that I can destroy their session. My tech stack includes jsp (html, js) and java. Any suggestions on how to ...

In a scenario where multiple fields need to be incremented, one can accomplish this by incrementing one field every time while also increasing the other field only if it exceeds a

When trying to decrement class_number, everything works fine. However, the issue lies with number_of_classes not being decremented due to the usage of the $gt operator. posts.update({ 'title':doc.title, 'author':doc.author, 'class ...

Has the user successfully authenticated with Google?

Possible Repetition: How to verify if a user is logged into their Google account using API? I'm working on a website that displays a Google Calendar. My query is: Can I determine whether a user is currently logged into a Google Account? If it&ap ...

Struggling to get moment().utc() to display a two-digit format for the month and year

Currently, I am tackling a bug that has surfaced in a birthday component within my application. This component pulls the date of birth from its props in the format 1997-08-16T00:00:00Z. The challenge I am facing is that when the date of birth is set in the ...

Best Practices for Storing User Data in Single Page Applications

While working on a Single Page Application (SPA) using AngularJS, I encountered an issue with storing user data in an Angular Value service. I realized that the data was not being shared between browser tabs, leading to constant requests to the server for ...

Tips for parsing a tsp library file with JavaScript

Looking for assistance with a tsp library file in JavaScript. The specific file, named file1.tsp, contains the following data: NAME: a280 COMMENT: drilling problem (Ludwig) TYPE: TSP DIMENSION: 280 EDGE_WEIGHT_TYPE: EUC_2D NODE_COORD_SECTION 1 288 149 ...

The randomly generated data retrieved through AJAX in the form of JSON is stored haphazardly within

I am currently working on retrieving details of various Twitch channel names stored in an array called user_arr. The goal is to fetch their information from twitch.tv. Below you can find the code, along with some insights: $(document).ready(function(){ v ...

Adjust the height automatically in extjs hbox layout with this quick guide

When I try to dynamically set data in this layout, the layout doesn't resize properly and the final result looks like this. This is the code I'm currently using: win = Ext.create('widget.window', { title: 'Layout Window&apo ...

Refresh jQuery CSS for active button whenever a different button is clicked

I want to enhance a group of buttons using jQuery. I aim to make the active button visually stand out so that users can easily identify it. These buttons are being created through a PHP foreach loop, as shown below: foreach($result as $row){ echo "< ...

Iterating through two variables and running tests every 1000 milliseconds

I am working with two variables: const frame = $('#avacweb_chat iframe'); let time = $('.date-and-time' , frame.contents()).last().text(); let newTime = setInterval(function() { let newT = $('.date-and-time' , frame.content ...

Jade: utilizing a Jade block within a Mixin by passing it as a string

I have come across a Jade template that includes a call to a mixin at a specific point. One of the parameters passed to this mixin is a lengthy HTML string which the mixin then prints using != The code looks like this: +createHTML({firstSection:'< ...

Is there a way to verify the success of a Firebase push event upon submitting a form?

Here is the code for my polymer form and JavaScript. It works well in pushing data. What I would like to achieve is a way to verify if the push operation was successful or not. If it was successful, I want to hide the form and display a confirmation messag ...

Having trouble setting dynamic state using the render method in React ES6

I'm attempting to add dynamic states using a method. The concept is that when I invoke the method from a render method, it should accept a parameter value to set dynamic state values. Below is my code: renderFeaturePermissionOptions( featureName ) { ...

Enabling JavaScript functions to accept a variable number of arguments

I am looking to enhance the versatility of the function below by enabling it to accept multiple callbacks to other functions if they are specified in the arguments. $(function() { function icisDashBox(colorElem, thisWidth, thisHeight, completeCallBack ...

The function getSelection().focusNode does not function properly within a specified ID

My current code allows for text to be bolded and unbolded using Window.getSelection(). I found the initial solution here: Bold/unbold selected text using Window.getSelection() It works perfectly without any issues. However, when I tried to modify the code ...