在 useEffect 中调用时钩子不更新

时间:2021-04-09 06:42:44

标签: javascript reactjs react-hooks

从我的 API 检索数据后,我在更新状态时遇到问题。 API 响应很好,但由于某种原因,我的 weatherData-hook 没有更新并返回 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"},
  ...
]

1 个答案:

答案 0 :(得分:4)

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 可以返回被拒绝的 promise,并且在处理响应时可能会出错,因此您应该将获取逻辑包含在 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)
    )
}