繁体   English   中英

Next.js 刷新页面后无法获取数据

[英]Cannot fetch data after refreshing the page in Next.js

我正在尝试使用从后端获取的数据创建一个简单的 Next.js 页面。 为了获取,我正在使用 useSWR。

如果我在运行 dev 后刷新页面或第一次打开它,我会收到 TypeScript 错误,因为 data.results(获取的对象的数据)object 未定义。 这让我相信 API 无法正常工作或获取功能配置错误。 然而,这两种情况都不是。

如果我评论包含已提取 object (data.results) 的 2 行,并从浏览器刷新,我会看到一个空白页面,这并不奇怪。 在那之后,如果我取消注释 console.log( data.results[1].name ) 并保存更改,我可以在浏览器控制台中看到产品名称。 第二次提到 data.results 也是如此。 很明显,数据获取是有效的,因为我可以在某些情况下看到数据。 在这个state中,如果我点击主页按钮,然后点击主页中的Prods按钮返回,它仍然有效。 它在控制台和页面中显示数据。 因此,只要我不刷新页面,它就可以工作。

在那之后(不评论这两行),如果我从浏览器刷新页面,我会再次收到 TypeError。

TypeScript 错误截图

在使用 useSWR 之前,我尝试使用 useEffect 和 useState 来达到相同的目的,但同样的事情发生了。 我也使用了公理但没有任何改变。 总之,无论我多么努力,我都无法使用从后端获取的内容创建一个简单的页面。 我觉得我缺少一个基础知识。 在问这个问题之前,我浏览了几页文档,但一无所获。

在下面的代码中,我尝试呈现一个主页按钮和第二个产品的名称。 我在上面提到的使用 data.results 的两行附近有评论。 在 index.js 中只有一个链接到此 Prods 页面的按钮。

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

您不会在浏览器的控制台选项卡上看到控制台 output,而是查看您的 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM