无法在 Next 中传递道具
Unable to pass props in Next
我正在使用 Next Js (React SSR) 制作服务器端渲染应用程序。
Index.js(在索引中调用另一个组件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
我的问题是,我正在尝试将道具从 layout
页面传递到 product
页面,道具是从 getInitialProps
(SSR) 接收的。但是你可以看到提供的示例,道具不起作用,它仍然为 this.props.stars
提供 undefined .
如果我将此代码移至 componentDidMount
并使用 setState
并将状态作为 props 传递将起作用,但这将不会在视图页面源中显示从 api 获取的数据。
注意: 请不要将此逻辑移动到 index.js 文件中,但在我的实际应用程序中它是动态路由页面,我将获取 api 根据在该页面上获取的查询参数。
如果你进入这个 link https://748d5.sse.codesandbox.io/ 并点击 ctrl + u
那么你会看到我所在的来源还需要从 api 获取的动态内容。
为了实现此动态内容(本例中的星星计数)仅在视图源中显示,我正在做所有这些是为了 SEO 目的。
简而言之,您不能从子组件 getInitialProps caveats 调用 getInitialProps
。
getInitialProps can not be used in children components, only in the default export of every page
您的 Layout
页面是 Home
的子组件。
如果你想调用 getInitialProps
,那么你要么需要在 Home
页面中定义 getInitialProps
,要么创建一个包装器组件来调用它自己的 getInitialProps
将使用此包装器组件包装页面的 default export PageComponet
:export default withStarsData(PageComponent)
;结果,这个包装器组件将传递 PageComponent
一些 props
.
如果你想做这个功能flexible/dynamic,那就用ctx's query
parameter with a 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;
我正在使用 Next Js (React SSR) 制作服务器端渲染应用程序。
Index.js(在索引中调用另一个组件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
我的问题是,我正在尝试将道具从 layout
页面传递到 product
页面,道具是从 getInitialProps
(SSR) 接收的。但是你可以看到提供的示例,道具不起作用,它仍然为 this.props.stars
提供 undefined .
如果我将此代码移至 componentDidMount
并使用 setState
并将状态作为 props 传递将起作用,但这将不会在视图页面源中显示从 api 获取的数据。
注意: 请不要将此逻辑移动到 index.js 文件中,但在我的实际应用程序中它是动态路由页面,我将获取 api 根据在该页面上获取的查询参数。
如果你进入这个 link https://748d5.sse.codesandbox.io/ 并点击 ctrl + u
那么你会看到我所在的来源还需要从 api 获取的动态内容。
为了实现此动态内容(本例中的星星计数)仅在视图源中显示,我正在做所有这些是为了 SEO 目的。
简而言之,您不能从子组件 getInitialProps caveats 调用 getInitialProps
。
getInitialProps can not be used in children components, only in the default export of every page
您的 Layout
页面是 Home
的子组件。
如果你想调用 getInitialProps
,那么你要么需要在 Home
页面中定义 getInitialProps
,要么创建一个包装器组件来调用它自己的 getInitialProps
将使用此包装器组件包装页面的 default export PageComponet
:export default withStarsData(PageComponent)
;结果,这个包装器组件将传递 PageComponent
一些 props
.
如果你想做这个功能flexible/dynamic,那就用ctx's query
parameter with a 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;