React useEffect 未按预期运行

React useEffect not behaving as expected

我正在使用 OpenWeatherAPI,我的获取工作正常。我能够使用 State 将成功获取的数据放入状态。控制台日志出现,我可以看到在网络选项卡中发出的请求。

但是发生了一些有趣的事情,我的 .map()ed 数据并没有像我预期的那样每次都呈现。我将编写代码,按保存,它会显示在屏幕上。但是,如果我刷新页面或重新启动服务器,它就不会出现。有时会在刷新几次后出现。

我很可能在挂钩系统上做错了什么。请指出我做错了什么。

我不能在 promise 解决后直接使用我放入 state 的列表,我需要过滤掉我刚刚在 state 中设置的响应,只得到我需要的 keys/vals 因此你为什么查看 filteredForecasts 的第二个状态。为什么它只是偶尔定期工作?我觉得我有所有正确的 null 检查 if 语句,但它仍然没有按预期工作...

import React from "react";
import WeatherCard from '../WeatherCard';
import "./WeatherList.scss";

const WeatherList = (props) => {
  return (
    <div className="weather-list-container">
      <WeatherCard />
    </div>
  );
};

export default WeatherList;
import React, { useState, useEffect } from "react";
import "./WeatherCard.scss";
import { getForecast } from "../../api/GET/getForecast";

const WeatherCard = () => {
  const [forecasts, setForecasts] = useState([]);
  const [filteredForecasts, setFilteredForecasts] = useState([]);

  useEffect(() => {
    getForecast()
      .then((res) => {
        const { list } = res;
        setForecasts(list);
      })
      .catch((err) => {
        console.log(err);
      });
  }, []);

  useEffect(() => {

    if (forecasts.length) {
      const uniqueForecasts = Array.from(
        new Set(allRelevantData.map((a) => a.day))
      ).map((day) => {
        return allRelevantData.find((a) => a.day === day);
      });

      setFilteredForecasts(uniqueForecasts);
    }
  }, []);

  const allRelevantData = Object.entries(forecasts).map(([key, value]) => {
    const dateTime = new Date(value.dt * 1000);
    const day = dateTime.getDay();

    const item = {
      day: day,
      temp: Math.round(value.main.temp),
      weatherMetaData: value.weather[0],
    };

    return item;
  });


  return filteredForecasts && filteredForecasts.map(({ day, temp, weatherMetaData }) => {
    return (
      <div className="weather-card">
        <div className="day-temperature-container">
          <span className="day">{day}</span>
          <span className="temperature">{temp}</span>
        </div>
        <div className="weather-description">
          <span
            className="icon weather"
            style={{
              background: `url(http://openweathermap.org/img/wn/${weatherMetaData.icon}.png)`,
            }}
          />
          <p>{weatherMetaData.description}</p>
        </div>
      </div>
    );
  });
};

export default WeatherCard;
import openWeatherConfig from '../../config/apiConfig';

const {baseUrl, apiKey, londonCityId} = openWeatherConfig;

export function getForecast(cityId = londonCityId) {
  return fetch(`${baseUrl}/forecast?id=${cityId}&units=metric&appid=${apiKey}`)
    .then(res => res.json());
}

问题

useEffect 仅当它是一个空数组依赖项时才在挂载上运行,在这种情况下,预测很可能是空的。

解决方案

filteredForecastforecast 状态的导数 属性。将其从状态中删除并在没有 React.useEffect.

的情况下使用它
  const allRelevantData = Object.entries(forecasts).map(([key, value]) => {
    const dateTime = new Date(value.dt * 1000);
    const day = dateTime.getDay();

    const item = {
      day: day,
      temp: Math.round(value.main.temp),
      weatherMetaData: value.weather[0],
    };

    return item;
  });

  let filteredForecasts = null; 
   
    if (forecasts.length) {
      filteredForecasts = Array.from(
        new Set(allRelevantData.map((a) => a.day))
      ).map((day) => {
        return allRelevantData.find((a) => a.day === day);
      });

  return /** JSX **/

您正在将一个空的依赖项数组传递给您的第二个(过滤预测)useEffect 调用,这意味着它将 运行 仅在组件安装时才会执行。如果您的第一个效果尚未返回,您过滤的预测将永远不会看到任何数据。

您可能根本不需要第二次 useEffect 调用。只需在预测返回第一个效果时计算它。