axios 不在刷新时获取,仅在第一次渲染时获取

axios doesnt fetch on refresh, only on first render

所以我一直在努力从 API 检索数据和/或检索本地 json 文件。我正在使用 React axios,但即使使用普通的获取方法,我也遇到了同样的问题。当我获取端点并保存代码时,我的 jsx 刷新并且数据出现在屏幕上但是当我刷新页面时,它不再存在并且在我一次又一次刷新时不会出现。我不知道我做错了什么。我试图检索父级的数据并将其设置为道具但仍然是同样的问题。

我的子组件:

import React, { useEffect, useState } from 'react';

import './Card.scss';

import axios from 'axios';

import { ellipsisIcon } from '../../constants/images';

import dataJson from './data.json';

const Card = ({ name, color, icon, currentTime }) => {
  const [data, setData] = useState([]);

  const [daily, setDaily] = useState([]);
  const [weekly, setWeekly] = useState([]);
  const [monthly, setMonthly] = useState([]);

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios.get('data.json');
      setData(result.data);
      setData(
        data.filter((item) => {
          return item.title === name;
        }),
      );

      setDaily(data[0].timeframes.daily);
      setWeekly(data[0].timeframes.weekly);
      setMonthly(data[0].timeframes.monthly);
    };
    fetchData();
  }, []);

  return (
    <div className="card" style={{ backgroundColor: `${color}` }}>
      <img src={icon} alt={`${name} icon`} />
      <div className="card__container bg-blue">
        <div className="card__top-container flex">
          <p className="text-white ">{name}</p>
          <div className="card__top__elipse-container">
            <img src={ellipsisIcon} alt="ellipsis" />
          </div>
        </div>
        <div className="card__bottom-container">
          {currentTime === 0 && (
            <>
              <h1 className="fs-900 text-white">{daily.current}hrs</h1>
              <div className="card__bottom__prev-container">
                <p className="text-accent ">
                  Yesterday -<span>{daily.previous}hrs</span>
                </p>
              </div>
            </>
          )}
          {currentTime === 1 && (
            <>
              <h1 className="fs-900 text-white">{weekly.current}hrs</h1>
              <div className="card__bottom__prev-container">
                <p className="text-accent ">
                  Last Week -<span>{weekly.previous}hrs</span>
                </p>
              </div>
            </>
          )}
          {currentTime === 2 && (
            <>
              <h1 className="fs-900 text-white">{monthly.current}hrs</h1>
              <div className="card__bottom__prev-container">
                <p className="text-accent">
                  Last Month -<span>{monthly.previous}hrs</span>
                </p>
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
};

export default Card;

我的应用(父应用):

import { useState, useEffect } from 'react';
import Card from './components/Card/Card';

import {
  pbImage,
  ellipsisIcon,
  exerciseIcon,
  playIcon,
  careIcon,
  socialIcon,
  studyIcon,
  workIcon,
} from './constants/images';

const cards = [
  {
    name: 'Exercise',
    color: 'hsl(var(--clr-exercise))',
    icon: exerciseIcon,
  },
  {
    name: 'Play',
    color: 'hsl(var(--clr-play))',
    icon: playIcon,
  },
  {
    name: 'Self Care',
    color: 'hsl(var(--clr-care))',
    icon: careIcon,
  },
  {
    name: 'Social',
    color: 'hsl(var(--clr-social))',
    icon: socialIcon,
  },
  {
    name: 'Study',
    color: 'hsl(var(--clr-study))',
    icon: studyIcon,
  },
  {
    name: 'Work',
    color: 'hsl(var(--clr-work))',
    icon: workIcon,
  },
];

function App() {
  const [selectedTime, setSelectedTime] = useState(2);
  return (
    <div className="app bg-dark">
      <div className="main__container grid">
        <div className="side__card-container">
          <div className="side__card__top flex">
            <div className="side__card__top__pb-container">
              <img
                src={pbImage}
                alt="pb"
                className="side__card__top__pb-image pb-image"
              />
            </div>
            <div className="side__card__top__person-container">
              <p className="fs-600 text-accent">Report for</p>
              <h2 className="fs-800 text-white">Jeremy Robson</h2>
            </div>
          </div>
          <div className="side__card__bottom">
            <div>Daily</div>
            <div>Weekly</div>
            <div>Monthly</div>
          </div>
        </div>
        {cards.map((card, _index) => (
          <Card
            key={_index}
            name={card.name}
            color={card.color}
            icon={card.icon}
            currentTime={selectedTime}
          />
        ))}
      </div>
    </div>
  );
}

export default App;

正如我在评论中提到的,状态是异步更新的。因此,在设置值后立即使用状态时应该小心。在您的情况下,您不应使用 data 状态,因为您不确定它是否具有值。试试改成这个。

  useEffect(() => {
    const fetchData = async () => {
      const result = await axios.get('data.json');
      const filteredData = result.data.filter((item) => {
          return item.title === name;
      })

      setData(filteredData);
      
      // make sure result data isn’t empty
      setDaily(result.data[0].timeframes.daily);
      setWeekly(result.data[0].timeframes.weekly);
      setMonthly(result.data[0].timeframes.monthly);
    };
    fetchData();
  }, []); // "[]" makes the useEffect callback only run after the first render