首页 > 解决方案 > Next.js 无法预渲染错误页面

问题描述

我最近开始在一个新项目上使用 Next.JS,它工作正常,但是当我在单击错误链接后抛出 404 错误时,我无法弄清楚如何在客户端保持我的布局状态处于活动状态。

感谢Adam 的 Wathan 文章,我能够在不同页面之间分享我的状态:

在主页上

在此处输入图像描述

在“关于”页面

在此处输入图像描述

但是,如果我单击“错误”,它将呈现 _error.tsx 而不保留我在输入中写入的数据。 在此处输入图像描述

尽管我提供了相同的布局,但该页面似乎在服务器端呈现了整个应用程序树。有没有像普通页面一样预取这个页面,避免在不使用像 Redux 这样的解决方案的情况下丢失一些信息?我注意到它非常熟悉,在这种情况下似乎有点太多了。

这是我的代码:pages/_error.tsx

import { getLayout } from "../components/layout/mainLayout"
import { withTranslation } from "../i18n";
import { FlexDirectionProperty } from "csstype";

const imgStyle = {
  maxWidth: "100%",
  maxHeight: "100%"
};

const figureStyle = {
  height: "80vh",
  display: "flex",
  justifyContent: "center",
  alignItems: "center",
  flexDirection: "column" as FlexDirectionProperty
};

const CustomError: any = ({ status, t }: any) => (
  <>
    <figure style={figureStyle}>
      <figcaption>
        <h1>Statut:{t('WELCOME')}</h1>
      </figcaption>
      <img
        alt="Showing a properly cat according the status code"
        src={`https://http.cat/${status}`}
        style={imgStyle}
      />
    </figure>
  </>
)

CustomError.getLayout = getLayout;

CustomError.getInitialProps = async ({ res, err }: any) => {
  const statusCode = res ? res.statusCode : err ? err.statusCode : null

  return {
    statusCode: statusCode,
    namespacesRequired: ["common"]
  }
};

export default withTranslation('common')(CustomError)

组件/布局/header.tsx

import Link from "next/link";
import Navbar from "react-bootstrap/Navbar";
import Nav from "react-bootstrap/Nav";
import Form from "react-bootstrap/Form";
import Button from "react-bootstrap/Button";
import { withTranslation, i18n } from "../../i18n";
import { capitalize } from "../../helpers/utils";
import Modal from "react-bootstrap/Modal";
import { useState } from "react";

const loadStamp = +new Date();

const Header: any = ({ t }: any) => {
  const [show, setShow] = useState(false);
  const [active, setActive] = useState("home");

  return (
    <>
      <Navbar fixed="top" bg="light">
        <Nav className="mr-auto" activeKey={active}>
          <Nav.Item>
            <Link href="/">
              <Navbar.Brand onClick={() => setActive("home")} href="/">Random Project</Navbar.Brand>
            </Link>
          </Nav.Item>
          ...
        </Nav>
      </Navbar>
    </>);
};

export default withTranslation("common")(Header);

组件/布局/mainLayout.tsx

import Header from "./header";
import "bootstrap/dist/css/bootstrap.min.css";
import "../../public/stylesheets/style.scss";

type LayoutProps = {
  title?: string;
  children: any;
};

const Layout: React.FunctionComponent<LayoutProps> = ({ children }) => (
  <>
    <Header />
    <main role="main" className="main">
      {children}
    </main>
  </>
);

export const getLayout: any = (page: any) => <Layout>{page}</Layout>

export default Layout

还有我的 _app.tsx

import React from 'react'
import App from 'next/app'
import { appWithTranslation } from '../i18n'

class MyApp extends App<any> {

    render() {
        const { Component, pageProps } = this.props
        const getLayout = Component.getLayout || ((page: any) => page)

        return (
            <>
                {getLayout(
                    <Component {...pageProps}></Component>
                )}
            </>
        )
    }
}

export default appWithTranslation(MyApp)

标签: reactjsnext.js

解决方案


推荐阅读