我正在使用 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;

Layout.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

我的问题是,我试图将 Prop 从 product 页面传递给 layout 页面,并且 Prop 是从 getInitialProps (SSR) 接收的。但是您可以在提供的示例中看到, Prop 不起作用,它仍然给 未定义的 对于 this.props.stars

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

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

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

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

最佳答案

简而言之,您不能从子组件调用 getInitialProps : getInitialProps caveats



您的 Layout 页面是 Home 的子组件。

如果您想调用 getInitialProps ,那么您要么需要在 getInitialProps 页面中定义 Home ,要么创建一个调用自己的 getInitialProps 的包装器组件,该包装器组件将使用此包装器组件包装页面的 default export PageComponet : export default withStarsData(PageComponent) ;结果,这个包装器组件将传递 PageComponent 一些 props

如果你想让这个函数灵活/动态,那么使用 ctxquery 参数和 dynamic route

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

工作示例 :

javascript - 无法在 Next 中传递 Prop-LMLPHP

组件/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;

关于javascript - 无法在 Next 中传递 Prop ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61111933/

10-09 22:55