Next.js:在静态导出期间向页面传递额外的道具?

Evg*_*nko 3 reactjs next.js

我正在尝试静态导出 next.js 应用程序。该文件说,网页对象只有两个值:pagequery。有没有办法将额外的道具传递给页面?

我试过为此使用query它,但似乎 next 的路由器不知道该路由的query对象。因此它不起作用。

换句话说,我在构建时有一个博客文章列表,我如何将它们内联到页面(页面组件)?

我猜react-static有一个routeInfo.json是为每条路线预取的。我想知道next.js中有没有类似的东西。

Evg*_*nko 5

UPD Apr 4 20 至少在next.js 9.3 中getStaticPropsgetStaticPaths

(完整示例)

const IndexPage: NextPage<{ names: string[] }> = (props) => {
  return (
    <main>
      <section>
        {props.names.map((name) => (
          <div key={name}>
            <Link href={`/users/${name}`}>
              <a>{name}</a>
            </Link>
          </div>
        ))}
      </section>
    </main>
  );
};

export const getStaticProps: GetStaticProps = async () => {
  const data: User[] = readJsonSync("./data.json");

  return {
    props: {
      names: data.map((user) => user.name),
    },
  };
};

export default IndexPage;
Run Code Online (Sandbox Code Playgroud)

UPD 12 月 4 日 19

有一个 RFCgetStaticProps可以解决这个问题:https : //github.com/zeit/next.js/issues/9524


这就是我的结果。

_app.js:

import React from "react";
import App, { Container } from "next/app";

import fs from "fs";
import { resolve, join } from "path";

export default class extends App {
  static async getInitialProps({ Component, ctx }) {
    const { req, asPath } = ctx;
    let pageProps = {};

    if (Component.getInitialProps) {
      pageProps = await Component.getInitialProps(ctx);
    }

    let p;
    if (req) {
      p = JSON.parse(
        fs.readFileSync(resolve(join("data", asPath, "route.json"))).toString()
      );
    } else {
      p = await (await fetch(`/data${asPath}/route.json`)).json();
    }

    return { pageProps: { ...pageProps, ...p } };
  }

  render() {
    const { Component, pageProps } = this.props;
    return (
      <Container>
        <Component {...pageProps} />
      </Container>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

在 next.config.js 中:

const fetch = require("isomorphic-unfetch");
const fs = require("fs");
const path = require("path");
const fse = require("fs-extra");
const withBundleAnalyzer = require("@next/bundle-analyzer")({
  enabled: false
});

module.exports = withBundleAnalyzer({
  webpack(config) {
    config.node = { fs: "empty", path: "empty" };
    return config;
  },
  async exportPathMap() {
    const response = await fetch(
      "https://jsonplaceholder.typicode.com/posts?_page=1"
    );
    const postList = await response.json();
    fs.writeFileSync(
      path.resolve(`data/route.json`),
      JSON.stringify({ postList }, null, 2)
    );
    for (let i = 0; i < postList.length; ++i) {
      const id = postList[i].id;
      const response = await fetch(
        `https://jsonplaceholder.typicode.com/posts/${id}`
      );
      const post = await response.json();
      const fn = path.resolve(`data/post/${id}/route.json`);

      await fse.outputFile(fn, JSON.stringify(post, null, 2));
    }

    const pages = postList.reduce(
      (pages, post) =>
        Object.assign({}, pages, {
          [`/post/${post.id}`]: {
            page: "/post"
          }
        }),
      {}
    );

    return Object.assign({}, pages, {
      "/": { page: "/" }
    });
  }
});

Run Code Online (Sandbox Code Playgroud)