简体   繁体   English

如何在 _app.js 中使用 getStaticProps 在 Next.js 的每个页面中显示从 api 获取的数据

[英]How to use getStaticProps in _app.js for showing data fetched from api in every pages in Next.js

To be specific I am showing data on the navbar from the API endpoint.具体来说,我在导航栏上显示来自 API 端点的数据。 And I want to use getStaticProps to get those data on all the pages.我想使用 getStaticProps 在所有页面上获取这些数据。 But the problem is I need to do getStaticProps on all the pages.但问题是我需要在所有页面上执行 getStaticProps 。

Can we do something like this and get data on all the pages as props?我们可以做这样的事情并获取所有页面上的数据作为道具吗?

//pages/_app.js
function MyApp({ Component, pageProps, navs }) {
  return (
    <>
      <Component {...pageProps} navs={navs} />
    </>
  );
}
export async function getStaticProps() {
  const res = await api.get("/api/v1/navs");
  const navs = res.data;
  return {
    props: {
      navs,
    },
    // revalidate: 60, // In seconds
  };
}

export default MyApp;

What could be the alternative way of doing this?这样做的替代方法是什么? Is there a way to manage a global state, so that it is used by all the pages?有没有办法管理全局 state,以便所有页面都使用它? I don't think we can use Context API to provide data to all the pages too.我不认为我们也可以使用 Context API 为所有页面提供数据。

Problem问题

NextJS doesn't currently support lifecycle methods in _app.js . NextJS 目前不支持_app.js中的生命周期方法。

Solution解决方案

Since the above isn't supported yet, you'll want to create a reusable getStaticProps function and export it from all pages .由于上述内容尚不支持,因此您需要创建一个可重用的getStaticProps function 并将其从所有页面导出。 Unfortunately, this does mean some WET code;不幸的是,这确实意味着一些 WET 代码; however, you can reduce some boilerplate by creating a HOC which wraps the page and also exports a getStaticProps function.但是,您可以通过创建一个包装页面并导出 getStaticProps function 的HOC来减少一些样板。

Alternatives备择方案

You can use getInitialProps within the _app.js file.您可以在_app.js文件中使用getInitialProps Unfortunately, this disables automatic static optimization across the entire application .不幸的是,这会禁用整个应用程序的自动 static 优化。

Demo演示

编辑静态优化列表

Code代码

components/Navigation组件/导航

import * as React from "react";
import Link from "next/link";
import { nav, navItem } from "./Navigation.module.css";

const Navigation = () => (
  <div className={nav}>
    {[
      { title: "Home", url: "/" },
      { title: "About", url: "/about" },
      { title: "Help", url: "/help" }
    ].map(({ title, url }) => (
      <div className={navItem} key={title}>
        <Link href={url}>
          {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
          <a>{title}</a>
        </Link>
      </div>
    ))}
  </div>
);

export default Navigation;

components/UsersList组件/用户列表

import * as React from "react";
import isEmpty from "lodash.isempty";
import { noUsers, title, userList, user } from "./UsersList.module.css";

const UsersList = ({ error, users, retrieved }) =>
  !retrieved ? (
    <p>Loading...</p>
  ) : !isEmpty(users) ? (
    <div className={userList}>
      <h1 className={title}>Statically Optimized User List</h1>
      {users.map(({ name }) => (
        <div className={user} key={name}>
          {name}
        </div>
      ))}
    </div>
  ) : (
    <div className={noUsers}>{error || "Failed to load users list"}</div>
  );

export default UsersList;

containers/withUsersList容器/withUsersList

import * as React from "react";
import axios from "axios";
import UsersList from "../../components/UsersList";

/**
 * A HOC that wraps a page and adds the UserList component to it.
 *
 * @function withUsersList
 * @param Component - a React component (page)
 * @returns {ReactElement}
 * @example withUsersList(Component)
 */
const withUsersList = (Component) => {
  const wrappedComponent = (props) => (
    <>
      <UsersList {...props} />
      <Component {...props} />
    </>
  );

  return wrappedComponent;
};

export const getStaticProps = async () => {
  try {
    const res = await axios.get("https://jsonplaceholder.typicode.com/users");

    return {
      props: {
        retrieved: true,
        users: res.data,
        error: ""
      }
    };
  } catch (error) {
    return {
      props: {
        retrieved: true,
        users: [],
        error: error.toString()
      }
    };
  }
};

export default withUsersList;

pages/_app.js页面/_app.js

import * as React from "react";
import Navigation from "../components/Navigation";

const App = ({ Component, pageProps }) => (
  <>
    <Navigation />
    <Component {...pageProps} />
  </>
);

export default App;

pages/about页/关于

import withUsersList, { getStaticProps } from "../containers/withUsersList";

const AboutPage = () => <div>About Us.</div>;

export { getStaticProps };

export default withUsersList(AboutPage);

pages/help页面/帮助

import withUsersList, { getStaticProps } from "../containers/withUsersList";

const HelpPage = () => <div>Find Help Here.</div>;

export { getStaticProps };

export default withUsersList(HelpPage);

pages/index页面/索引

import withUsersList, { getStaticProps } from "../containers/withUsersList";

const IndexPage = () => <div>Hello World.</div>;

export { getStaticProps };

export default withUsersList(IndexPage);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM