javascript - 无法在 Next 中传递 props

标签 javascript reactjs next.js server-side-rendering

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

Index.js(只需在索引中调用另一个组件布局)

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 从 layout 页面传递到 product 页面,并且 Prop 是从 getInitialProps (SSR)接收的..但是您可以在提供的示例中看到, Prop 不起作用,并且它仍然为 this.props.stars 提供 undefined

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

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

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

为了实现仅在 View 源中显示的动态内容(本例中的星星数),我所做的所有这些都是为了 SEO 目的。

最佳答案

简而言之,您无法从子组件调用 getInitialProps:getInitialProps caveats

getInitialProps can not be used in children components, only in the default export of every page

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

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

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

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

工作示例:

Edit GetInitialProps Wrapper

<小时/>

components/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 中传递 props,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61111933/

相关文章:

javascript - 将值插入模板 AngularJS

reactjs - react Hook : Idiomatic way to ensure that useEffect runs only when the contents of an array argument to the custom hook change

next.js - nextjs - 页面样式最初未加载,导致巨大的图标和损坏的 CSS

mongodb - 如何在同构或 SSR 应用程序中使用 MongoDB Stitch Auth?

reactjs - craco 和 antd 的主题切换怎么用?

reactjs - 预期服务器 HTML 在 NextJs 的 <nav> 中包含匹配的 <svg>

javascript - 父容器发生转换时如何强制固定位置?

javascript - 如何动态创建 '@-Keyframe' CSS动画?

javascript - 迭代枚举对象中多个数组的键值对

html - 如何在 react native 中对齐屏幕底部的按钮?