Lior Zelitchenok
Lior Zelitchenok

Reputation: 11

React-query with NextJs routing

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>
)

}

Upvotes: 1

Views: 2180

Answers (1)

TkDodo
TkDodo

Reputation: 28733

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.

Upvotes: 4

Related Questions