我正在使用 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
。
如果你想让这个函数灵活/动态,那么使用 ctx的 query
参数带有 dynamic route .
这是一个相当复杂的解决方案,但简而言之,它允许主页 (/
) 和布局 (/layout
) 页面获取相同的数据。如果您不想多次获取数据,而是获取一次然后在页面之间共享,那么您将需要使用像 redux 这样的高阶状态提供程序。 .
工作示例:
<小时/>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/