Query values lost on page refresh in Next js? [Example given]

ぐ巨炮叔叔 提交于 2020-12-05 19:10:52

问题


I am making a simple Next Js application which has only two pages..

index.tsx:

import React from "react";
import Link from "next/link";

export default function Index() {
  return (
    <div>
      <Link
        href={{
          pathname: "/about",
          query: { candidateId: 8432 }
        }}
        as="about"
      >
        Go to the about page
      </Link>
    </div>
  );
}

As per the above code, on click Go to the about page it goes to about page and using query I also receive the passed query values in about page.

about.tsx

import React from "react";
import Router, { withRouter } from "next/router";

function About({ router: { query } }: any) {
  return (
    <div>
      Candidate Id: <b> {query.candidateId} </b>
    </div>
  );
}

export default withRouter(About);

This displays the value but on page refresh while we are in /about page, the candidateId received gets disappeared.

Requirement: Kindly help me to retain the query value passed down from one page to another page even on page refresh.

Note: As per my requirement I should not display the canidateId on url while navigating and hence I am using as approach.. I know I can achieve it if I remove as but I cannot remove that here in index page while navigating.. Reason is this will lead to displaying candidateId in the url which is not intended..

Tried this solution: https://stackoverflow.com/a/62974489/7785337 but this gives empty query object on refresh of page.

Stuck for very long time with this please kindly help me.


回答1:


Try to delete the as="about" and then navigate again to the "about" page, the issue should be gone. Codesandbox




回答2:


If you do not want to use the query parameter you may need to create a "store" that saves your variable that persist throughout your pages.

Sample code as follows.

//candidatestore.js
export const CandidateStoreContext = createContext()

export const useCandidateStore = () => {
    const context = useContext(CandidateStoreContext)
    if (!context) {
        throw new Error(`useStore must be used within a CandidateStoreContext`)
    }
    return context
}

export const CandidateStoreProvider = ({ children }) => {

    const [candidateId, setCandidateId] = useState(null);

    return (
        <CandidateStoreContext.Provider value={{ candidateId, setCandidateId }}>        
                        {children}    
        </CandidateStoreContext.Provider >

    )
}

Then you need to wrap the Provider around your app like

<CandidateStoreProvider><App /></CandidateStoreProvider>

This way you can use anywhere as follows both in your index page and your about page.

const { candidateId, setCandidateId } = useCandidateStore()

UseContext

In your codes, it should probably look something like that.

import React from "react";
import Link from "next/link";
import { useCandidateStore } from './candidatestore'

export default function Index() {
  const { candidateId, setCandidateId } = useCandidateStore()
  useEffect(() => {
     setCandidateId(thecandidateId)
  })
  return (
    <div>
      <Link
        href={{
          pathname: "/about",
        }}
        as="about"
      >
        Go to the about page
      </Link>
    </div>
  );
}

function About({ router: { query } }: any) {

  const { candidateId, setCandidateId } = useCandidateStore()
  return (
    <div>
      Candidate Id: <b> {candidateId} </b>
    </div>
  );
}



回答3:


My best bet would be to store the candidateId in an encrypted session on the client side. You could read/verify cookies in getServerSideProps() and pass their contents to the page component. If this sounds feasible, I'd recommend checking out the next-iron-session.

Another approach would be to check if candidateId exists in the query object in getServerSideProps(). If it does then pass it straight to the page component. If not, either get it elsewhere, redirect, or pass some default value. Append the following starter code to your about.tsx:

/* ... */

export function getServerSideProps({ query }: any) {
  // if query object was received, return it as a router prop:
  if (query.candidateId) {
    return { props: { router: { query } } };
  }
  // obtain candidateId elsewhere, redirect or fallback to some default value:
  /* ... */
  return { props: { router: { query: { candidateId: 8432 } } } };
}



回答4:


Update to Next.JS 10. It comes with Automatic Resolving of href which fixes your problem.



来源:https://stackoverflow.com/questions/64781234/query-values-lost-on-page-refresh-in-next-js-example-given

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!