Search code examples
javascriptreactjsnext.jsreact-querynext-router

NextJS Router doesn't reload data until page refocus


Currently working with NextJS, but struggling to make an indexing page of sorts. With the router, I'm trying to get the page number by doing this:

let router = useRouter()
let page = isNaN(router.query.page) ? 1 : parseInt(router.query.page);

So that when I go to page=1, page=2 etc, I get new sets of data. The functionality for this is called in the same main component, and is a React Query function:

const {data, status} = useQuery(["keycaps", {manu: manuId}, {prof: profileId}, {col: colorId}, {stat: statusId}], getKeycaps)

And said function looks like this:

const getKeycaps = async(key) => {
    const manuId = key.queryKey[1].manu
    const profileIds = key.queryKey[2].prof.map(id => `profile.id=${id}`)
    const colorIds = key.queryKey[3].col.map(id => `filter_colors.id=${id}`)
    const statId = key.queryKey[4].stat

    const profileQueryString = profileIds.join("&")
    const colorQueryString = colorIds.join("&")

    let urlParams = new URLSearchParams(document.location.search);
    let page = urlParams.get("page") == null ? 1 : parseInt(urlParams.get("page"));

    let start = (page * 10) - 10

    const data = await axios(`
        ${process.env.REACT_APP_STRAPI_API}/keycaps?${manuId ? 'manufacturer.id=' + manuId + '&' : ''}${profileQueryString ? profileQueryString + '&' : ''}${colorQueryString ? colorQueryString + '&' : ''}_start=${start}&_limit=10`)
    return data.data
}

When initially loading pages, like directly pasting the url of the index in (i.e. keycaps?page=2), it will get all the results all fine. However, if I start using navigational buttons like this:

<Link href={`/keycaps?page=${page - 1}`}> // next/link
    <div className="w-32 rounded-lg cursor-pointer">
        Prev
    </div>
</Link>
<Link href={`/keycaps?page=${page + 1}`}>
    <div className="w-32 rounded-lg cursor-pointer">
        Next
    </div>
</Link>

The whole thing starts to break down. Essentially, the page doesn't actually reload any data or results until the page is unfocused. So, if I press the Next button to go to the next page, it won't load the data until I do something like tab to a new window or check a different internet tab, and then when I come back, the data will all magically load within a second. I've tried this with next build && next start too, and this produces the same results. I just want to get the page results when the next and prev page buttons are pressed, and in a way that doesn't require the user to switch tabs to get content.

I will note that I do have a getStaticProps on this as well. It does the following:

export async function getStaticProps() {
    const allKeycaps = (await getAllKeycaps() || 'Error')
    return {
        props: { allKeycaps }
    }
}

Which will call an api script, and said script does this:

async function fetchAPI(query, {variables} = {}) {
    const res = await fetch(`${process.env.REACT_APP_STRAPI_API}/graphql`, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
            query,
            variables,
        }),
    })

    const json = await res.json()
    
    if (json.errors) {
        console.error(json.errors)
        throw new Error('Failed to fetch API')
    }

    console.log('json', json.data, variables)

    return json.data
}
/* Keycap related grabs */

export async function getAllKeycaps() {
    const data = await fetchAPI(
        `
        {
            keycaps {
                id
                slug
                name
                published_at
                updatedAt
                profile {
                    id
                    name
                }
                manufacturer {
                    id
                    name
                    lead
                }
                status {
                    id
                    name
                }
                colors
                filter_colors {
                    color
                }
                kits
                designer
                thumb {
                    formats
                }
            }
        }
        `
    )
    return data
}

Anyone know how to get this to work? To navigate between indexes like this? I've been trying to look for Next tutorials that use navigations like page 1, page 2 etc but all I can find is examples of blog articles with slugs, no index searches of any kind. Thanks a lot in advance.


Solution

  • Answer found:

    When setting data and status using useQuery

    const curPage = router.query.page == null ? 1 : router.query.page
    
    const {data, status} = useQuery(["keycaps", {manu: manuId}, {prof: profileId}, {col: colorId}, {stat: statusId}, {page: curPage}], getKeycaps)
    

    And then, in getKeycaps

    const page = key.queryKey[5].page
    

    I guess the "urlParams" approach wasn't a good one? Or at least, not one that was updating quick enough. So passing through the router page number seems to work better.