gpt4 book ai didi

javascript - 使用NextJS使用Class Components和getInitialProps进行SSR,render方法有未定义的数据

转载 作者:行者123 更新时间:2023-12-02 21:42:57 30 4
gpt4 key购买 nike

我对 JavaScript/React/NextJS 相当陌生。我已经编写了一个 React 应用程序,现在正在尝试对其进行转换,以便所有内容都可以在服务器上呈现。

我浏览了 https://nextjs.org/learn/basics/getting-started 上的教程然后我尝试将这些知识应用到我的应用程序中。

我的应用程序有以下要求

  • 我有一个主要细节场景。主页呈现文章列表,单击其中一篇文章会将用户带到文章详细信息。
  • 我想要干净的网址,例如“/article/123”而不是“article?id=123”。
  • 我正在使用第三方库从服务器获取数据,因此我必须使用 Promise 来获取数据
  • 我需要使用类组件而不是功能组件(由于其他原因无法移动到功能组件)。
  • 我希望所有渲染都发生在服务器而不是客户端

我不清楚如何在“getInitialProps”中调用我的第 3 方库中的异步方法并返回数据。我尝试的任何方法都不起作用,谷歌搜索也没有帮助。

我的项目结构是

- components
|- header.js
|- footer.js
|- layout.js
- pages
|- index.js
|- article
|- [id].js
- scripts
|- utils.js

index.js 仅呈现 2 篇文章的 2 个链接

export default function Index() {
return (
<div>
<Link href="/article/[id]" as={`/article/1`}>
<a>Article 1</a>
</Link>
<Link href="/article/[id]" as={`/article/2`}>
<a>Article 2</a>
</Link>
</div>
);
}

utils.js有一个util方法来调用第3方库方法

export function getDataFromThirdPartyLib(articleId) { 
return thirdPartyLib.getMyData({
"articleId" : articleId,
}).then(function (item) {
return item;
});
}

article/[id].js 有

 function getData(articleId){
console.log("getData")
getDataFromThirdPartyLib(articleId)
.then((item) => {
console.log("got data")
return {
item: item
}
});
}

class ArticleDetails extends React.Component {

static async getInitialProps(ctx) {
const data = await getData(articleId);
// I also tried the following
// const data = getData(articleId);

return{
data : data
}
}

render() {
console.log("IN RENDER")
console.log("this.props.data") // THIS IS UNDEFINED
// my HTML
}
}

问题:

控制台日志显示数据在 render() 中始终未定义。我可以从获取数据中看到我的日志记录,并且获取了数据,但是这些在我的渲染日志记录之后呈现,因此一旦获取数据,渲染就不会刷新。

不同的尝试1

我尝试在我的组件定义中使用“getData”(与在其外部相对),但这总是失败,因为它说“getData”不是一个函数。

 class ArticleDetails extends React.Component {

static async getInitialProps(ctx) {
const data = await getData(articleId); // FAILS AS SAYS getData is not a function

return{
data : data
}
}

getData(articleId){
console.log("getData")
getDataFromThirdPartyLib(articleId)
.then((item) => {
return {
item: item
}
});
}

render() {
console.log("IN RENDER")
console.log(this.props.data) // THIS IS UNDEFINED
// my HTML
}
}

不同的尝试2

我尝试将“getData”中的逻辑直接放在“getInitialProps”中,但这也不起作用,因为它说 getInitialProps 必须返回一个对象。

 class ArticleDetails extends React.Component {

static async getInitialProps(ctx) {
getDataFromThirdPartyLib(articleId)
.then((item) => {
return {
data: data
}
});
}

render() {
console.log("IN RENDER")
console.log(this.props.data) // THIS IS UNDEFINED
// my HTML
}
}

工作版本 - 但不是 SSR

我能让它工作的唯一方法就是像 React 应用程序中的类组件一样编写它。但我相信“componentDidMount”不是在服务器上调用的,而是在客户端中调用的。因此,这挫败了我让所有内容在服务器中渲染的尝试。

class ArticleDetails  extends React.Component {

state = {
item: null,


componentDidMount() {
this.getData();
}


getData(articleId){
console.log("getData")
getDataFromThirdPartyLib(articleId)
.then((item) => {
self.setState({
item: item
}
});
}

render() {
console.log("IN RENDER")
console.log(this.state.item) // THIS HAS A VALUE
// my HTML
}

}

史蒂夫·霍尔加多提供的解决方案

问题是我的“getData”方法没有像史蒂夫所说的那样返回 promise 。

但是,我的“getData”方法比我最初在这篇文章中提出的方法要复杂一些,这就是为什么当我第一次尝试史蒂夫的解决方案时它不起作用。

我的 getData 嵌套了两个 promise 。如果我把返回放在两个 promise 上,它就会完美地运作。

function getData(articleId){
return getDataFromThirdPartyLib(articleId)
.then((item) => {

return getSecondBitOfDataFromThirdPartyLib(item)
.then((extraInfo) => {
return {
item: item,
extraInfo : extraInfo
}
});

return {
item: item
}
});
}

最佳答案

您需要从article/[id].js中的getData返回promise:

function getData(articleId){
// return promise here
return getDataFromThirdPartyLib(articleId)
.then((item) => {
return {
item: item
}
});
}

...否则隐式返回undefined

另外,您从哪里获取articleId

它应该来自网址吗?

static async getInitialProps(ctx) {
const articleId = ctx.query.id;
const data = await getData(articleId);

return {
data: data
}
}

希望这有帮助。

关于javascript - 使用NextJS使用Class Components和getInitialProps进行SSR,render方法有未定义的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60326174/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com