无法在 Next 中传递props

IT技术 javascript reactjs next.js server-side-rendering
2021-05-12 23:44:07

我正在使用 Next Js (React SSR) 制作服务器端渲染应用程序。

Index.js(简单地调用index中的另一个组件Layout)

import Layout from "./layout";
import React from "react";

class Home extends React.Component {
  render() {
    return (
      <div>
        <Layout />
      </div>
    );
  }
}

export default Home;

布局.js

import React from "react";
import Product from "./product";

class Layout extends React.Component {
  static async getInitialProps() {
    const res = await fetch("https://api.github.com/repos/developit/preact");
    console.log(res);
    const json = await res.json();
    return { stars: json.stargazers_count };
  }

  componentDidMount() {
    if (localStorage.getItem("userLoggedIn")) {
      //Get products details for logged in user api
      //For now let us consider the same api
      // const res = fetch("https://api.github.com/repos/developit/preact");
      // const json = res.json(); // better use it inside try .. catch
      // return { stars: json.stargazers_count };
    } else {
      // Get product details for guest user api
      //For now let us consider the same api
      // const res = fetch("https://api.github.com/repos/developit/preact");
      // const json = res.json(); 
      // return { stars: json.stargazers_count };
    }
  }

  render() {
    return (
      <div>
        This is layout page
        <Product stars={this.props.stars} />
      </div>
    );
  }
}

export default Layout;

完整的简单应用示例在这里https : //codesandbox.io/s/nextjs-getinitialprops-748d5

我在这里的问题是,我试图通过props来product从网页layout页面和props从收到getInitialProps(SSR)..但是你可以看到在所提供的示例中,props都没有工作,它仍然给出不确定this.props.stars

如果我将此代码移入componentDidMount并使用setState和传递状态作为props将起作用,但不会在视图页面源中显示从 api 获取的数据。

注意:请不要将此逻辑移动到它工作的 index.js 文件中,但在我的实际应用程序中它是动态路由页面,我将根据在该页面上获取的查询参数获取 api。

如果您进入此链接https://748d5.sse.codesandbox.io/并单击,ctrl + u那么您将看到我还需要从 api 获取的动态内容的源代码。

为了实现这个动态内容(在这个例子中星星数)只在查看源中显示,我正在做所有这些都是为了 SEO 目的。

1个回答

简而言之,您不能getInitialProps从子组件调用getInitialProps 警告

getInitialProps不能在子组件中使用,只能在每个页面的默认导出中使用

您的Layout页面是 的子组件Home

如果你想打电话getInitialProps,那么你要么需要定义getInitialProps从内Home页或创建一个包装组件调用自身的getInitialProps抚慰页面的default export PageComponet这个包装组件:export default withStarsData(PageComponent); 结果,这个包装器组件将传递PageComponent一些props.

如果要使此功能灵活/动态,请使用ctxquery参数和动态路由

这是一个需要理解的相当复杂的解决方案,但简而言之,它允许主页 ( /) 和布局 ( /layout) 页面获取相同的数据。如果您不想多次获取数据,而是要获取一次然后在页面之间共享,那么您将需要使用像redux这样的高阶状态提供程序

工作示例

编辑 GetInitialProps 包装器


组件/withStars/index.js

import React from "react";
import fetch from "isomorphic-unfetch";

// 1.) this function accepts a page Component and...
const withStars = WrappedComponent => {

  // 7.) if stars data is present, returns <WrappedComponent {...props} /> with props
  // else if there's an error, returns the error
  // else returns a "Loading..." indicator
  const FetchStarsData = props =>
    props.stars ? (
      <WrappedComponent {...props} />
    ) : props.error ? (
      <div>Fetch error: {props.error} </div>
    ) : (
      <div>Loading...</div>
    );

  // 3.) this first calls the above function's getInitialProps
  FetchStarsData.getInitialProps = async ctx => {

    // 4.) here's where we fetch "stars" data
    let stars;
    let error;
    try {
      const res = await fetch("https://api.github.com/repos/developit/preact");
      const json = await res.json();
      stars = json.stargazers_count;
    } catch (e) {
      error = e.toString();
    }

    // 5.) optionally this will call the <WrappedComponent/> 
    // getInitialProps if it has been defined
    if (WrappedComponent.getInitialProps)
      await WrappedComponent.getInitialProps(ctx);

    // 6.) this returns stars/error data to the FetchStarsData function above
    return { stars, error };
  };

  // 2.) ...returns the result of the "FetchStarsData" function
  return FetchStarsData;
};

export default withStars;