我正在制作一个服务器端呈现应用程序,使用下一个Js (React )。
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
我的问题是,我试图将道具从product
页面传递到layout
页面,而道具则是从getInitialProps
收到的。但是在提供的示例中可以看到,道具没有工作,它仍然为提供了用于this.props.stars
的未定义的。
如果我将这段代码移动到componentDidMount
中,并使用setState
和传递状态作为支持,那么这将不会显示视图页面源中从api获取的数据。
注意:请不要将此逻辑移动到它工作的index.js文件中,但在我的实际应用程序中,它是动态路由页,我将根据在该页面上获取的查询参数获取。
如果您进入这个链接https://748d5.sse.codesandbox.io/并单击ctrl + u
,那么您将看到我也需要从api获取的动态内容的源代码。
为了实现这一动态内容(在本例中星号计数),仅在视图源中显示,我正在做所有这些,这是为了SEO的目的。
发布于 2020-04-09 01:13:17
简而言之,您不能从子组件:getInitialProps
调用getInitialProps警告。
getInitialProps 不能用于子组件,只能在每个页面的默认导出中使用。
Layout
页面是Home
的子组件。
如果您想要调用getInitialProps
,那么您要么需要在Home
页面中定义getInitialProps
,要么创建一个包装器组件来调用它自己的getInitialProps
,该包装器组件将页面的default export PageComponet
封装到这个包装器组件:export default withStarsData(PageComponent)
;因此,这个包装器组件将传递PageComponent
一些props
。
如果您想使这个函数具有灵活性/动态性,那么使用ctx的query
参数和一个动态路径。
这是一个需要理解的相当复杂的解决方案,但简而言之,它允许主(/
)和布局(/layout
)页面获取相同的数据。如果您不想多次获取数据,而是获取一次,然后在页面之间共享,那么您将需要使用像剩馀这样的高阶状态提供程序。
工作示例
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;
https://stackoverflow.com/questions/61111933
复制相似问题