NextJS动态路由与模态重新加载导致叠加背景消失

IT技术 javascript reactjs next.js
2021-04-29 05:26:16

我有一个非常简单的 NextJS 应用程序,打开一个页面将更新 URL,但不会触发导航,而是在模式中显示内容。URL 仍然反映实际页面位置,任何刷新都会将用户带到那里。

当模态打开时,我仍然希望将原始内容保留在背景中褪色的页面之外,并且模态应该出现在前面。

现在,当我的模态打开时,原始背景内容会消失而不是在背景中褪色。

我已经在代码沙箱中复制了这个问题: https://codesandbox.io/s/replicating-backdrop-disappearing-rqt21?file=/pages/index.js

在代码沙盒示例中,当您单击登录按钮时,您将看到模式有效,但原始背景消失了。我怎样才能让背景内容只是褪色。

请帮忙。

3个回答

正如文档所述,您尝试做的事情是不可能的/不切实际的。您不能在加载另一个页面的同时保持页面加载。如果你想保持加载相同的页面,那么你必须使用带有浅路由的动态路由,我觉得这对于静态身份验证页面来说太过分了。

相反,您应该创建一个Layout包裹整个应用程序组件(使用_app.js),或者有选择地使用可重用的布局组件包裹每个路由。

附带说明一下,我建议避免多次导入相同的第 3 方全局 CSS。如果您多次导入它,则表明您很可能应该将 Next 的自定义应用程序页面用于全局样式表(不是必需的,但应该消除多余的样式表导入)。

演示:

编辑 NextJS 布局


组件/布局/index.jsx

/* eslint-disable jsx-a11y/anchor-is-valid */
import Link from "next/link";

export default function Layout({ children }) {
  return (
    <>
      <Link href="/">
        <a className="link">Home</a>
      </Link>
      <Link href="/login">
        <a className="link">Login</a>
      </Link>
      <Link href="/signup">
        <a className="link">Signup</a>
      </Link>
      <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Itaque eos id
        agere, ut a se dolores, morbos, debilitates repellant. Duo Reges:
        constructio interrete. Qualis ista philosophia est, quae non interitum
        afferat pravitatis, sed sit contenta mediocritate vitiorum? Vide ne ista
        sint Manliana vestra aut maiora etiam, si imperes quod facere non
        possim. <i>Quid censes in Latino fore?</i> Ita relinquet duas, de quibus
        etiam atque etiam consideret. <i>Quippe: habes enim a rhetoribus;</i>{" "}
        <b>Sum praesertim illa perdiscere ludus esset.</b>{" "}
      </p>
      {children}
    </>
  );
}

/* eslint-enable jsx-a11y/anchor-is-valid */

页面/_app.js

import "react-responsive-modal/styles.css";
import Layout from "../components/Layout";
import "../styles.css";

export default function App({ Component, pageProps }) {
  return (
    <Layout>
      <Component {...pageProps} />
    </Layout>
  );
}

页面/index.js

export default function IndexPage() {
  return <h1>Index Page</h1>;
}

页面/登录.js

import Router from "next/router";
import { Modal } from "react-responsive-modal";

export default function Login() {
  return (
    <Modal center blockScroll open onClose={() => Router.push("/")}>
      <p>Login</p>
    </Modal>
  );
}

页面/signup.js

import Router from "next/router";
import { Modal } from "react-responsive-modal";

export default function SignupPage() {
  return (
    <Modal center blockScroll open onClose={() => Router.push("/")}>
      <p>Signup</p>
    </Modal>
  );
}

正如评论中提到的,您正在触发导航,因为您的链接指向不同的页面。

为了实现您想要的行为,您可以在同一页面内使用查询参数与浅路由结合使用

export default function IndexPage() {
    const router = useRouter();

    return (
        <div>
            <Link href="/?login=true" as="/login" shallow={true}>
                <a>Login</a>
            </Link>
            <Modal
                center
                blockScroll={true}
                open={!!router.query.login}
                onClose={() => router.push('/', undefined, { shallow: true })}
            >
                <p>Hello World!</p>
            </Modal>
        </div>
    );
}

对于那些想在 NextJs 中使用模态组件的人,本文展示了如何将模态注入客户端浏览器,因为文档对象在服务器端渲染不可用。

https://devrecipes.net/modal-component-with-next-js/

文章不是我写的,但这是它的使用方式

https://github.com/Malik-Idrees/dj-events-frontend/blob/main/components/Modal.js