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