Javascript 无法在下一步中传递道具
我正在使用nextjs(reactssr)制作一个服务器端渲染应用程序 Index.js(只需在索引中调用另一个组件布局)Javascript 无法在下一步中传递道具,javascript,reactjs,next.js,server-side-rendering,Javascript,Reactjs,Next.js,Server Side Rendering,我正在使用nextjs(reactssr)制作一个服务器端渲染应用程序 Index.js(只需在索引中调用另一个组件布局) 从“/Layout”导入布局; 从“React”导入React; 类Home扩展了React.Component{ render(){ 返回( ); } } 导出默认主页; Layout.js import React from "react"; import Product from "./product"; class Layout extends React.Co
从“/Layout”导入布局;
从“React”导入React;
类Home扩展了React.Component{
render(){
返回(
);
}
}
导出默认主页;
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;
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;
从“React”导入React;
从“/Product”导入产品;
类布局扩展了React.Component{
静态异步getInitialProps(){
const res=等待获取(“https://api.github.com/repos/developit/preact");
控制台日志(res);
const json=await res.json();
返回{stars:json.stargazers\u count};
}
componentDidMount(){
if(localStorage.getItem(“userLoggedIn”)){
//获取登录用户api的产品详细信息
现在让我们考虑同样的API。
//const res=fetch(“https://api.github.com/repos/developit/preact");
//const json=res.json();//最好在try..catch中使用它
//返回{stars:json.stargazers\u count};
}否则{
//获取来宾用户api的产品详细信息
现在让我们考虑同样的API。
//const res=fetch(“https://api.github.com/repos/developit/preact");
//const json=res.json();
//返回{stars:json.stargazers\u count};
}
}
render(){
返回(
这是布局页面
);
}
}
导出默认布局;
完整的简单应用程序示例如下所示:
我这里的问题是,我试图从布局页面将道具传递到产品页面,并且从获取初始道具(SSR)。。但是您可以在提供的示例中看到,props不起作用,它仍然为this.props.stars
提供未定义的
如果我将此代码移动到componentDidMount
中,使用setState
并将状态作为道具传递,则会起作用,但不会在查看页面源中显示从api获取的数据
注意:请不要将此逻辑移到index.js文件中,但在我的实际应用程序中,它是动态路由页面,我将根据该页面上获取的查询参数获取api
如果您进入这个链接并单击ctrl+u
,那么您将看到我所在的源代码也需要从api获取动态内容
为了实现此动态内容(本例中为星星数)仅在源代码视图中显示,我正在执行所有这些操作,这是为了SEO目的。简而言之,您不能从子组件调用getInitialProps
getInitialProps不能在子组件中使用,只能在每个页面的默认导出中使用
您的布局
页面是主页
的子组件
如果要调用getInitialProps
,然后,您需要在主页
页面中定义getInitialProps
,或者创建一个包装器组件,该组件调用自己的getInitialProps
,该组件将使用此包装器组件包装页面的默认导出页面组件:使用tarsdata导出默认值(PageComponent)
;因此,这个包装器组件将传递一些PageComponent
道具
如果要使此函数灵活/动态,请将的query
参数与
这是一个相当复杂的解决方案,但简而言之,它允许主页(/
)和版面(/layout
)页面获取相同的数据。如果您不想多次获取数据,而是只获取一次,然后在页面之间共享,那么您需要使用高阶状态提供程序,如
工作示例:
组件/withStars/index.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;
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;
从“React”导入React;
从“同构取消蚀刻”导入提取;
//1.)此函数接受页面组件并。。。
const withStars=WrappedComponent=>{
//7.)如果存在stars数据,则返回道具
//否则,如果出现错误,则返回错误
//else返回“正在加载…”指示器
const FetchStarsData=props=>
道具,明星(
):道具错误(
获取错误:{props.error}
) : (
加载。。。
);
//3.)首先调用上述函数的getInitialProps
FetchStarsData.getInitialProps=async ctx=>{
//4.)这里是我们获取“明星”数据的地方
让星星;
让错误;
试一试{
const res=等待获取(“https://api.github.com/repos/developit/preact");
const json=await res.json();
stars=json.stargazers\u count;
}捕获(e){
错误=e.toString();
}
//5.)这将调用
//getInitialProps(如果已定义)
if(WrappedComponent.getInitialProps)
等待WrappedComponent.getInitialProps(ctx);
//6.)这会将星号/错误数据返回到上面的FetchStarsData函数
返回{stars,error};
};
//2.)返回“FetchStarsData”函数的结果
返回数据;
};
使用STAR导出默认值;
谢谢您如此详细的回答。为了得到一个好的答案,我苦苦挣扎了很长时间,并为此表示感谢。。并通过沙盒感谢您的时间和工作示例。。我会在我真正的项目中实施,如果有任何疑问,我会回复你。你的回答也帮了我很多!如何使用json中的数据制作地图?使用github repository API示例,我需要获取所有名称和ID,并将它们打印在我的索引页和概要文件上。示例代码的主要问题是,数据
属性最初未定义,因为它是异步定义的(这意味着解析请求和将data
定义为JSON
)需要时间