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

ioekq8ef  于 2023-04-11  发布在  其他
关注(0)|答案(2)|浏览(171)

我尝试创建一个简单的Next.js页面,其中包含从后端获取的数据。对于获取,我使用useSWR。
如果我在运行dev后第一次刷新页面或打开它,我会得到一个TypeScript错误,因为data.results(fetched object的data)对象没有定义。这让我相信要么API不工作,要么抓取函数配置错误。然而这两种情况都不是。
如果我注解了包含所获取对象的两行(data.results),并从浏览器刷新,我可以看到一个空页面,没有惊喜。(data.results[1].name)并保存更改我可以在浏览器控制台中看到产品的名称。第二次提到data.results也是如此。所以很明显,数据抓取工作,因为我可以看到在某些情况下的数据.在这种状态下,如果我点击主页按钮,然后点击主页中的产品按钮回来,它仍然可以工作。它在控制台和页面中显示数据。所以只要我不刷新页面,它就可以工作。
在那之后(不注解那两行),如果我从浏览器刷新页面,我会再次得到TypeError。

在useSWR之前,我尝试了useEffect和useState,用于相同的目的,但发生了同样的事情。我也使用了axiom,但没有任何改变。总之,无论我多么努力,我都无法使用从后端获取的内容创建一个简单的页面。我觉得我错过了一个基础知识。在提出这个问题之前,我翻阅了几页文档,但什么都没有。
在下面的代码中,我尝试渲染一个按钮到主页和第二个产品的名称。我在上面提到的使用data.results的2行附近有注解。在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
bweufnob

bweufnob1#

你有没有尝试过服务器端渲染?如果你从后端获取数据,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
shstlldc

shstlldc2#

强文本checkout this image to have solution

只需在数据后添加?标记,这将检查天气数据是否存在

<div>
  <h1>{data?.results[1].name}</h1>
  <div>
    <p>{post?.id}</p>
    <p>{post?.body}</p>
  </div>
</div>

相关问题