最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Query values lost on page refresh in Next js? [Example given] - Stack Overflow

programmeradmin6浏览0评论

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: but this gives empty query object on refresh of page.

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

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./a/62974489/7785337 but this gives empty query object on refresh of page.

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

Share Improve this question edited Nov 20, 2020 at 4:24 Undefined asked Nov 11, 2020 at 5:59 UndefinedUndefined 1,0216 gold badges27 silver badges52 bronze badges 6
  • 1 AFAIK, "route state" is fairly transient, it really only exists during the route transition. Reloading the page doesn't reload the transition. I think you would need to persist the passed data to localStorage, or whatever you have available, that is accessible after a page load/reload. – Drew Reese Commented Nov 11, 2020 at 8:09
  • @DrewReese, Thanks for your ment and I think some other people also facing the same issue like here stackoverflow./questions/61891845/… and the proposed solution dosn't work for me.. If you could help me then please fork my codesandbox with your solution and post it as answer please.. I am just requesting if you could to do.. Because I see things in a different way from yours and I am learning a lot from you.. Please help me if you could .. Thanks.. – Undefined Commented Nov 11, 2020 at 8:22
  • @DrewReese, Bro can you help me here stackoverflow./questions/65504354/… ? – Undefined Commented Dec 30, 2020 at 9:04
  • @DrewReese, Can we make use of React context api in such case? – Undefined Commented Dec 30, 2020 at 9:05
  • Looks like TJ has a pretty good handle on that one. I don't disagree with anything he's said there. Without seeing your actual code and based entirely on his word and my examination of the react-metrics docs I'd say, yeah, the React Context API could potentially help here, though it seems react-metrics may already have its own context and provider. – Drew Reese Commented Dec 30, 2020 at 9:38
 |  Show 1 more ment

5 Answers 5

Reset to default 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>
  );
}

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

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

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 ponent. If this sounds feasible, I'd remend 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 ponent. 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 } } } };
}

index.tsx file

Keep the code same as it is.

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

AboutUs.tsx

Code starts from here

Adding router as a dependency in the useEffect the issue should get solved.

  import Router, { useRouter } from "next/router";
  import React, { useState, useEffect } from 'react';

  function About({ router: { query } }: any) {
    const route = userRouter();
    const [candidateId, setCandidateid] = useState();

    useEffect(() => {
    const {candidateId} = router.query  
    if(candidateId) {
     setCandidateid(candidateid)
   }},[router])  //Here goes the dependency

    return (
      <div>
        Candidate Id: <b> {candidateId} </b>
      </div>
    );
  }
  
  export default (About);
发布评论

评论列表(0)

  1. 暂无评论