1

I have a page with few queries and it's all working until I update the URL params and then react-query stops working and also disappear from dev-tools.

When I click on a row it triggers the handleRowClick function which update the URL with params, and then react query stops working.

1.First Image

2.Clicking on a row ( Update URL params ) Second Image

const Volumes: NextPage = () => {
const apiRef = useGridApiRef()

const [volumes, setVolumes] = useState<IDataset[] | undefined>(undefined)
const [isOpen, setOpen] = useState(false)
const [rightWingData, setRightWingData] = useState<IDataset | undefined>(undefined)
const [searchValue, setSearch] = useState('')
const [volumeId, setVolumeId] = useState('')

const { isLoading, data } = useVolumeData()
const { isLoading: searchIsLoading, data: searchData } = useSearchVolumes(searchValue)
const { isLoading: volumeByIdLoading, data: volumeByIdData } = useVolumeDataById(volumeId)

const router = useRouter()

useEffect(() => {
    if(router.isReady && router.query?.id && !rightWingData){
        const volumeId = router.query.id.toString()
        setVolumeId(volumeId)
    }

    if (!isLoading && data && !searchData) {
        setVolumes(data.data.result)
    }
    else if (!searchIsLoading) {
        setVolumes(searchData)
    }

    if(!volumeByIdLoading && volumeByIdData){
        showVolumeData(volumeByIdData)
    }
}, [data, isLoading, searchIsLoading, searchData, isOpen, rightWingData, volumeByIdLoading, volumeByIdData])


const handleRowClick = (rowData: IRowData) => {
    showVolumeData(rowData.row)
    Router.push({
        pathname: '/volumes',
        query: { id: rowData.row.id},
    })
}

const showVolumeData = (volumeData: IDataset) => {
    apiRef.current.updateColumns(thinColumns)
    setRightWingData(volumeData)
    setOpen(true)
    setVolumeId('')
}

const closeRightWing = () => {
    setOpen(false)
    Router.push('/volumes')
    apiRef.current.updateColumns(columns)
}

if (isLoading || !volumes) return <h1>Is Loading...</h1>

return (
    <div className={`volumes ${isOpen ? "open" : "close"}`}>
        <div className="volumes-table">
            <InfTable setSearch={setSearch} searchValue={searchValue} apiRef={apiRef}
                rows={volumes} columns={columns} initialState={initialState} onRowClick={handleRowClick} />
        </div>
        {rightWingData &&
            <div className="right-wing-wrapper" >
                <VolumeRightWing volume={rightWingData} onClose={closeRightWing} />
            </div>
        }
    </div>
)

}

function MyApp({ Component, pageProps }: AppProps) {
const queryClient = new QueryClient()

return (
    <QueryClientProvider client={queryClient}>
        <Layout>
            <Component {...pageProps} />
            <ReactQueryDevtools initialIsOpen={false} position="bottom-right" />
        </Layout>
    </QueryClientProvider>
)

}

5
  • you need to show us some code please, otherwise, it is impossible to help. Commented Apr 10, 2022 at 11:27
  • Please provide enough code so others can better understand or reproduce the problem. Commented Apr 10, 2022 at 23:07
  • Can you show where / how the queryClient is created? I have a hunch that an unstable client could be the cause. Commented Apr 11, 2022 at 7:17
  • @TkDodo - I added the code snippet for the queryClient Commented Apr 11, 2022 at 7:26
  • @TkDodo - The problem was that the queryClient was created inside the component every-time it rerenders, so I moved it outside the component. However I wonder why every time the URL changes it rerenders the entire App. Is there a way to prevent it in next.js? Commented Apr 11, 2022 at 7:41

1 Answer 1

4

as shown in the code, you are re-creating a new QueryClient inside the App component:

function MyApp({ Component, pageProps }: AppProps) {
  const queryClient = new QueryClient()

which means that every time the App re-renders, you throw away the Query Cache (which is stored inside the client).

This is likely what happens when you change the route params. If you cannot create the client outside of MyApp (e.g. because you are using server-side rendering), it is advised to create a stable client:

function MyApp({ Component, pageProps }: AppProps) {
  const [queryClient] = React.useState(() => new QueryClient())

this is also shown in the SSR docs.

Sign up to request clarification or add additional context in comments.

2 Comments

I created the client outside of the App component and it works. The problem was that when the URL changes next.js rerenders the App component.
@LiorZelitchenok Thanks, extracting create of QueryClient instance fixed this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.