#useSearchParams() causing infinite loop

1 messages · Page 1 of 1 (latest)

celest kraken
#

I have a dashboard app that displays a table. I would like it so that when a user clicks a column to sort, enters a filter, etc. the URL be updated with the current state of the table so that it can be shared, bookmarked, etc.
I have found the useSearchParams() hook but implementing it seems to be causing an infinite re-render loop.

The structure of my app is as follows:

  1. My component (built with TanStack Table) calls a custom hook (useTableHelper) to set initial state like page number, page size, sorts, filters, etc.
  2. That output is passed into a custom hook (useQueryHelper) that fetches the data via an API based on passed in state. This uses TanStack Query.
  3. That data is used to render a table

I have tried to set and update the URL in both the useTableHelper hook and the useQueryHelper hook. Obviously I am doing something wrong. I've looked at the docs, done some tutorials, etc. but can't seem to work this out.
Any help is greatly appreciated.

vernal kraken
#

What does the setSearchParams look like in your code?

#

This smells like a coding error from inlining it.

#

The typical way this happens:

<button onClick={setSearchParams(data)} ...
<button onClick={() => setSearchParams(data)} ...

celest kraken
#

I'm sure it is a coding error 😀

I have two useEffect() statements. I was hoping that one would set the initial URL, for example ?page=0 , by calling the page state setter. That one has an empty dependency array.

The second useEffect() has a dependency on my pagination state variable that I was intending to initially set. This useEffect() calls setSearchParams() like this:

//This state is set in a custom hook in another file but this is the definition
const [pagination, setPagination] = useState(<PaginationState>{pageIndex: 0, pageSize: 30});
useEffect(() => {
  setSearchParams({pagination.pageIndex.toString(),
  pagination.pageSize.toString()})
}, [pagination]) 

Looking at the pagination state variable in the console, I can see that I can set the page from the URL and the data is fetched from the back end, but then it resets to the default values in useState()

Thanks for your help. As you can probably tell, I'm new to React and front end development. I've done back end exclusively for the past few years.

vernal kraken
#

It's better if you setSearchParams directly on the event that change pagination, instead of useEffect.

#

If you comment that out the useEffect, does the looping stop?

#

setSearchParams({pagination.pageIndex.toString(), pagination.pageSize.toString()}) doesn't look right to me, does your terminal give you an warning about this?

celest kraken
#

If I comment out the useEffect without any dependencies, the URL updates as expected. What I can't do though is set the page in the URL manually. It always reverts back to the default page, 0. My pagination state has a backing interface that has both pageIndex and pageSize properties. That may explain why it looks strange.

I do have buttons that control page turns; I can try to place the setSearchParams there but I'm still not sure if I can get the bookmarking/copy paste URL functionality I was looking for.

keen edge
#

I've recently implemented something similar. Are you tying in to Tanstack table's PaginationState? I have my hook returning 3 functions, getPaginationState, setPaginationState and onPaginationChange. getPaginationState just takes the searchparams and returns them as a PaginationState object. The setPaginationState function takes the paginationState and calls setSearchParams. The onPaginationChange function returns an Updater<PaginationState> function that calls the updater passing in the old pagination state (from getPaginationState) and then calls setPaginationState with the upated PaginationState. Then in the Tanstack table options I just set state.pagination to the result of getPaginationState and onPaginationChange to the function from my hook. I have no useEffects anywhere in that code.

#

I should also mention that in my Pagination component, it is just calling "table.setPageIndex()". so that in turn calls onPaginationChange.

keen edge