Next.js 刷新页面后无法获取数据
Cannot fetch data after refreshing the page in Next.js
我正在尝试使用从后端获取的数据创建一个简单的 Next.js 页面。为了获取,我正在使用 useSWR。
如果我在 运行 开发后第一次刷新页面或打开它,我会收到 TypeScript 错误,因为 data.results(获取的对象的数据)对象未定义。这让我相信 API 不工作或获取功能配置错误。然而这两者都不是。
如果我评论包含获取对象的 2 行 (data.results),并从浏览器刷新,我会看到一个空白页面,这并不奇怪。在那之后,如果我取消评论
console.log(data.results[1].name
) 并保存更改 我可以在浏览器控制台中看到产品名称。第二次提到 data.results 也是如此。很明显,数据获取是有效的,因为我可以在某些情况下看到数据。在这种状态下,如果我点击主页按钮,然后点击主页中的Prods按钮返回,它仍然有效。它在控制台和页面中显示数据。所以只要我不刷新页面它就可以工作。
之后(不注释这两行),如果我从浏览器刷新页面,我会再次收到 TypeError。
在使用 useSWR 之前,我尝试使用 useEffect 和 useState 来达到相同的目的,但同样的事情发生了。我也使用了公理但没有任何改变。总之,无论我多么努力,我都无法使用从后端获取的内容创建一个简单的页面。我觉得我缺少一个基础知识。在问这个问题之前,我浏览了几页文档,但什么也没有。
在下面的代码中,我尝试呈现一个主页按钮和第二个产品的名称。我在上面提到的使用 data.results 的两行附近有评论。在 index.js 中只有一个链接到此产品页面的按钮。
import React, { useEffect, useState } from 'react';
import useSWR from 'swr'
import Link from "next/link"
import {Button} from '@mantine/core';
const fetcher = async (url, headers) => await fetch(url, {'method': 'GET', headers}).then(res => res.json())
function Prods() {
const product_url = 'http://127.0.0.1:8000/api/product/'
const headers = {
'Content-type': 'application/json',
'Authorization': `Token 9824eda0dd38b631b4aedf192899651cba91be53`
}
const { data, error } = useSWR([product_url, headers], fetcher)
console.log(data.results[1].name) //if commented, refreshed and then uncommented it works.
return (
<div>
<Link href="/" passHref>
<Button className = "m-1">
Homepage
</Button>
</Link>
{/* {data.results[1].name} //if commented, refreshed and then uncommented it works. */}
</div>
)
}
export default Prods
您是否为此尝试过服务器端渲染?如果您从后端获取数据,getServerSideProps 是在 Next 应用程序中执行此操作的正确位置。
import { GetServerSideProps } from "next";
...
export const getServerSideProps: GetServerSideProps = async (ctx) => {
const fetcher = async (url, headers) => await fetch(url, {'method': 'GET', headers}).then(res => res.json())
const product_url = 'http://127.0.0.1:8000/api/product/'
const headers = {
'Content-type': 'application/json',
'Authorization': `Token 9824eda0dd38b631b4aedf192899651cba91be53`
}
const { data, error } = useSWR([product_url, headers], fetcher)
console.log(data.results[1].name)
return {
props: {}
}
}
export default Prods
您不会在浏览器的控制台选项卡上看到控制台输出,而是查看您的 IDE 终端。
或者,我会像下面那样做
import useSWR from 'swr'
import Link from "next/link"
import {Button} from '@mantine/core';
function Prods() {
const fetcher = async (url, headers) => await fetch(url, {'method': 'GET', headers}).then(res => res.json())
const product_url = 'http://127.0.0.1:8000/api/product/'
const headers = {
'Content-type': 'application/json',
'Authorization': `Token 9824eda0dd38b631b4aedf192899651cba91be53`
const { data, error } = useSWR([product_url, headers], fetcher)
if (error) {
return(<p>Loading failed...</p>);
}
if (!data) {
return(<h1>Loading...</h1>);
}
return (
<div>
<Link href="/" passHref>
<Button className = "m-1">
Homepage
</Button>
</Link>
{data.results[1].name}
</div>
);
}
export default Prods
或
import useSWR from 'swr'
import Link from "next/link"
import {Button} from '@mantine/core';
function Prods() {
const fetcher = async (url, headers) => await fetch(url, {'method': 'GET', headers}).then(res => res.json())
const product_url = 'http://127.0.0.1:8000/api/product/'
const headers = {
'Content-type': 'application/json',
'Authorization': `Token 9824eda0dd38b631b4aedf192899651cba91be53`
const { data, error } = useSWR([product_url, headers], fetcher)
let pageContent;
if (error) {
pageContent = (<p>Loading failed...</p>);
}
else if (!data) {
pageContent = (<h1>Loading...</h1>);
}
else {
pageContent = (<p>data.results[1].name</p>);
}
return (
<div>
<Link href="/" passHref>
<Button className = "m-1">
Homepage
</Button>
</Link>
{pageContent}
</div>
);
}
export default Prods
我正在尝试使用从后端获取的数据创建一个简单的 Next.js 页面。为了获取,我正在使用 useSWR。
如果我在 运行 开发后第一次刷新页面或打开它,我会收到 TypeScript 错误,因为 data.results(获取的对象的数据)对象未定义。这让我相信 API 不工作或获取功能配置错误。然而这两者都不是。
如果我评论包含获取对象的 2 行 (data.results),并从浏览器刷新,我会看到一个空白页面,这并不奇怪。在那之后,如果我取消评论
console.log(data.results[1].name
) 并保存更改 我可以在浏览器控制台中看到产品名称。第二次提到 data.results 也是如此。很明显,数据获取是有效的,因为我可以在某些情况下看到数据。在这种状态下,如果我点击主页按钮,然后点击主页中的Prods按钮返回,它仍然有效。它在控制台和页面中显示数据。所以只要我不刷新页面它就可以工作。
之后(不注释这两行),如果我从浏览器刷新页面,我会再次收到 TypeError。
在使用 useSWR 之前,我尝试使用 useEffect 和 useState 来达到相同的目的,但同样的事情发生了。我也使用了公理但没有任何改变。总之,无论我多么努力,我都无法使用从后端获取的内容创建一个简单的页面。我觉得我缺少一个基础知识。在问这个问题之前,我浏览了几页文档,但什么也没有。
在下面的代码中,我尝试呈现一个主页按钮和第二个产品的名称。我在上面提到的使用 data.results 的两行附近有评论。在 index.js 中只有一个链接到此产品页面的按钮。
import React, { useEffect, useState } from 'react';
import useSWR from 'swr'
import Link from "next/link"
import {Button} from '@mantine/core';
const fetcher = async (url, headers) => await fetch(url, {'method': 'GET', headers}).then(res => res.json())
function Prods() {
const product_url = 'http://127.0.0.1:8000/api/product/'
const headers = {
'Content-type': 'application/json',
'Authorization': `Token 9824eda0dd38b631b4aedf192899651cba91be53`
}
const { data, error } = useSWR([product_url, headers], fetcher)
console.log(data.results[1].name) //if commented, refreshed and then uncommented it works.
return (
<div>
<Link href="/" passHref>
<Button className = "m-1">
Homepage
</Button>
</Link>
{/* {data.results[1].name} //if commented, refreshed and then uncommented it works. */}
</div>
)
}
export default Prods
您是否为此尝试过服务器端渲染?如果您从后端获取数据,getServerSideProps 是在 Next 应用程序中执行此操作的正确位置。
import { GetServerSideProps } from "next";
...
export const getServerSideProps: GetServerSideProps = async (ctx) => {
const fetcher = async (url, headers) => await fetch(url, {'method': 'GET', headers}).then(res => res.json())
const product_url = 'http://127.0.0.1:8000/api/product/'
const headers = {
'Content-type': 'application/json',
'Authorization': `Token 9824eda0dd38b631b4aedf192899651cba91be53`
}
const { data, error } = useSWR([product_url, headers], fetcher)
console.log(data.results[1].name)
return {
props: {}
}
}
export default Prods
您不会在浏览器的控制台选项卡上看到控制台输出,而是查看您的 IDE 终端。
或者,我会像下面那样做
import useSWR from 'swr'
import Link from "next/link"
import {Button} from '@mantine/core';
function Prods() {
const fetcher = async (url, headers) => await fetch(url, {'method': 'GET', headers}).then(res => res.json())
const product_url = 'http://127.0.0.1:8000/api/product/'
const headers = {
'Content-type': 'application/json',
'Authorization': `Token 9824eda0dd38b631b4aedf192899651cba91be53`
const { data, error } = useSWR([product_url, headers], fetcher)
if (error) {
return(<p>Loading failed...</p>);
}
if (!data) {
return(<h1>Loading...</h1>);
}
return (
<div>
<Link href="/" passHref>
<Button className = "m-1">
Homepage
</Button>
</Link>
{data.results[1].name}
</div>
);
}
export default Prods
或
import useSWR from 'swr'
import Link from "next/link"
import {Button} from '@mantine/core';
function Prods() {
const fetcher = async (url, headers) => await fetch(url, {'method': 'GET', headers}).then(res => res.json())
const product_url = 'http://127.0.0.1:8000/api/product/'
const headers = {
'Content-type': 'application/json',
'Authorization': `Token 9824eda0dd38b631b4aedf192899651cba91be53`
const { data, error } = useSWR([product_url, headers], fetcher)
let pageContent;
if (error) {
pageContent = (<p>Loading failed...</p>);
}
else if (!data) {
pageContent = (<h1>Loading...</h1>);
}
else {
pageContent = (<p>data.results[1].name</p>);
}
return (
<div>
<Link href="/" passHref>
<Button className = "m-1">
Homepage
</Button>
</Link>
{pageContent}
</div>
);
}
export default Prods