У меня возникла проблема с обновлением состояния после получения данных из моего API. Ответ API в порядке, но по какой-то причине мой хук weatherData не обновляется и возвращает undefined. Что я делаю неправильно?

Код:

const renderForecastTable = ({ weatherData }) => (
    <table>
        <thead>
            <th>Tid</th><th>Temperatur</th><th>Vind</th><th>Nederbörd</th>
        </thead>
        <tbody>
        {
        weatherData.Map(hour => 
            <tr>
                <td>{hour.Time}</td><td>{hour.Temp}</td>
                <td>{hour.WindSpeed} m/s {hour.WindDirection} grader</td>
                <td>{hour.AvgPrecipitationIntensity} mm</td>
            </tr>)
            }
        </tbody>
    </table>
)

const Weather = (props) => {
    const [weatherData, setWeatherData] = useState([]);
    const [loading, setLoading] = useState(true);
    const location = useLocation();

    useEffect(() => {
        const getWeather = async () => {
            const response = await fetch(`weather`);
            const json = await response.json();
            setWeatherData(json);
            setLoading(false);
        }
        getWeather();
    }, [])

    return(
        loading ? <></> : renderForecastTable(weatherData)
    )
}

export default Weather;

JSON-ответ:

[
  {"time":"4/9/2021 8:00:00 AM","temp":"6","windDirection":"216","windSpeed":"8.7","avgPrecipitationIntensity":"0"},
  {"time":"4/9/2021 9:00:00 AM","temp":"5.5","windDirection":"213","windSpeed":"7.9","avgPrecipitationIntensity":"0.2"},
  {"time":"4/9/2021 10:00:00 AM","temp":"4.7","windDirection":"218","windSpeed":"7.1","avgPrecipitationIntensity":"0.3"},
  {"time":"4/9/2021 11:00:00 AM","temp":"5.5","windDirection":"214","windSpeed":"7.3","avgPrecipitationIntensity":"0.3"},
  ...
]
2
claytonnes 9 Апр 2021 в 09:42

1 ответ

Лучший ответ

renderForecastTable использует аргумент и пытается деструктурировать свойство weatherData, но ему передается массив состояний weatherData, renderForecastTable(weatherData). Похоже, у вас тоже есть опечатка, weatherData.Map, вероятно, должно быть weatherData.map с функцией "map" в нижнем регистре. Поскольку weatherData определен как массив, я предполагаю, что вы хотели просто передать его функции renderForecastTable.

Использовать массив weatherData, без деструктуризации и исправить опечатку "map".

const renderForecastTable = (weatherData) => (
    <table>
        <thead>
            <th>Tid</th><th>Temperatur</th><th>Vind</th><th>Nederbörd</th>
        </thead>
        <tbody>
        {
        weatherData.map(hour => 
            <tr>
                <td>{hour.Time}</td><td>{hour.Temp}</td>
                <td>{hour.WindSpeed} m/s {hour.WindDirection} grader</td>
                <td>{hour.AvgPrecipitationIntensity} mm</td>
            </tr>)
            }
        </tbody>
    </table>
);

fetch может возвращать отклоненные обещания, и при обработке ответа могут возникать ошибки, поэтому вы должны заключить логику выборки в try/catch.

const Weather = (props) => {
    const [weatherData, setWeatherData] = useState([]);
    const [loading, setLoading] = useState(true);
    const location = useLocation();

    useEffect(() => {
        const getWeather = async () => {
            try {
                const response = await fetch(`weather`);
                const json = await response.json();
                setWeatherData(json);
            } catch(error) {
                // handle any rejected promises or thrown errors processing response
            } finally {
                setLoading(false);
            }
        }
        getWeather();
    }, [])

    return(
        loading ? null : renderForecastTable(weatherData)
    )
}
3
Drew Reese 9 Апр 2021 в 07:21