Next js 页面刷新时查询值丢失?[示例]

IT技术 javascript reactjs next.js server-side-rendering
2021-05-13 23:58:59

我正在制作一个只有两页的简单 Next Js 应用程序。

索引.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>
  );
}

根据上面的代码,单击Go to the about page它会转到 about 页面并使用queryI 还接收有关页面中传递的查询值。

关于.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);

这会显示该值,但在我们处于页面时刷新/about页面时,candidateId接收到的值消失了。

要求:即使在页面刷新时,也请帮助我保留从一个页面传递到另一个页面的查询值。

注意:根据我的要求,我不应该canidateId在导航时显示on url,因此我正在使用as方法..我知道如果我删除我可以实现它as但我无法在导航时在索引页面中删除它..原因是这会导致在不打算的 url 中显示CandidateId..

尝试了这个解决方案:https : //stackoverflow.com/a/62974489/7785337但这在页面刷新时给出了空的查询对象。

卡住了很长时间,请帮助我。

编辑dawn-microservice-sho7z

4个回答

如果您不想使用查询参数,您可能需要创建一个“存储”来保存在整个页面中持续存在的变量。

示例代码如下。

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

    )
}

然后您需要将 Provider 包裹在您的应用程序周围,例如

<CandidateStoreProvider><App /></CandidateStoreProvider>

通过这种方式,您可以在索引页面和关于页面中使用以下任何位置。

const { candidateId, setCandidateId } = useCandidateStore()

使用上下文

在您的代码中,它可能看起来像那样。

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

更新到 Next.JS 10。它带有自动解析 href 功能,可以解决您的问题。

尝试删除as="about"然后再次导航到“关于”页面,问题应该消失了。 代码沙盒

我最好的选择是将其存储candidateId在客户端的加密会话中。您可以读取/验证 cookiegetServerSideProps()并将其内容传递给页面组件。如果这听起来可行,我建议您查看next-iron-session

另一种方法是检查是否candidateId存在于查询对象getServerSideProps()如果是,则将其直接传递给页面组件。如果没有,请在别处获取它、重定向或传递一些默认值。将以下启动代码附加到您的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 } } } };
}