【问题标题】:Next.js. How to call component's getInitialProps in Layout下一个.js。如何在 Layout 中调用组件的 getInitialProps
【发布时间】:2019-05-08 03:39:07
【问题描述】:

我将页眉组件添加到布局,但我不想为我想要使用 getInitialProps 的每个页面从布局发送道具到页眉

layout.js

import Header from './header'
export default ({title}) => (
      <div>
        <Head>
          <title>{ title }</title>
          <meta charSet='utf-8' />
        </Head>

        <Header />

        {children}
      </div>
    )

header.js

export default class Header extends Component {
    static async getInitialProps () {
      const headerResponse = await fetch(someapi)
      return headerResponse;
    }
    render() {
        console.log({props: this.props})
        return (
            <div></div>
        );
    }
}

控制台:道具:{}

App.js

  import Layout from './layout'
  import Page from './page'
  import axios from 'axios'

const app =  (props) => (
  <Layout >
    <Page {...props}/>
  </Layout>
)

app.getInitialProps = async function(){
  try {
    const response = await axios.get(someUrl)
    return response.data;

  } catch(e) {
    throw new Error(e);
  }
}

export default app

我想在 Header 组件中使用 get initial props 但它没有触发

【问题讨论】:

  • getInitialProps 仅在您的应用程序(页面)的顶层可用,但是您可以在组件内传递道具

标签: javascript node.js next.js


【解决方案1】:

编辑:2021 年这样做的方式:

// with typescript remove type if you need a pure javascript solution
// _app.tsx or _app.jsx
import type { AppProps } from 'next/app';

import Layout from '../components/Layout';

export default function App({ Component, pageProps }: AppProps) {

  return (
    <Layout {...pageProps}>
      <Component {...pageProps} />
    </Layout>
  );
}

// In order to pass props from your component you may need either `getStaticProps` or `getServerSideProps`.
// You should definitely not do that inside your `_app.tsx` to avoid rendering your whole app in SSR;
// Example for SSR
export async function getServerSideProps() {
  // Fetch data from external API
  const res = await fetch(`https://.../data`)
  const data = await res.json()

  // Pass data to the page via props
  return { props: { data } }
}

Next.js 使用 App 组件来初始化页面。您可以覆盖它并控制页面初始化。

您可以做的是,将您的逻辑放入 _app 覆盖并将其传递给您的子组件,例如使用 Layout 组件。

创建page/_app.js

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

import Layout from '../components/Layout'

export default class MyApp extends App {
  static async getInitialProps({ Component, router, ctx }) {
    let pageProps = {}
    

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

    /* your own logic */

    return { pageProps }
  }

  render () {
    const { Component, pageProps } = this.props

    return (
      <Container>
        <Layout {...pageProps}>
          <Component {...pageProps} />
        </Layout>
      </Container>
    )
  }
}

githubgithub有一个很好的例子

【讨论】:

  • 这是完美的,我可以在每个页面渲染之前将其用作 getInitialProps() 的一种全局拦截器。谢谢!
  • 这个答案很有帮助,但已经过时了。 1-容器已弃用。 2- getInitialProps({ Component, router, ctx }) -> getInitialProps(ctx)。 3- Component.getInitialProps(ctx) -> App.getInitialProps(ctx)。欲了解更多信息:nextjs.org/docs/advanced-features/custom-app
  • 如果我不想在我的应用程序的每个页面上禁用静态页面生成怎么办?我不能在我的_app.js 中使用getInitialProps,因为Next 会用它渲染每个页面...假设我有2 个布局:adminPanelLayoutblogLayout,我希望博客布局是静态服务的,而管理布局是@ 987654332@
  • @Baterka 我已经用 2021 年的方式更新了我的初始帖子,Vercel 团队自我最初的回复以来取得了很大的进步。现在无需对整个应用程序进行 SSR 就可以做到这一点非常简单
  • 假设我有一个组件,我在其中呈现帖子列表,我通过 fetch 到 API 获取帖子列表,并且我需要在每次页面加载时更新此列表,以及当我转到 / post/38283 或 /post/38726,还有另一个 API 调用可通过 id 获取特定详细信息,因此我还需要新数据 + 需要在将生成的页面发送到客户端之前注入标头,处理此流程的正确方法是什么?
猜你喜欢
  • 2020-03-07
  • 2022-06-24
  • 2018-03-05
  • 1970-01-01
  • 2021-12-11
  • 2020-07-20
  • 1970-01-01
  • 2020-01-01
  • 2018-02-13
相关资源
最近更新 更多