【问题标题】:Calling only once two functions in useEffect在 useEffect 中只调用一次两个函数
【发布时间】:2020-08-17 23:41:34
【问题描述】:

我尝试在我的 useEffect 挂钩中调用两个函数

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

export const LocalWeather = () => {
  const APP_KEY = "XXX";
  const [userPlace, setUserPlace] = useState([]);
  const [localWeather, setLocalWeather] = useState([]);

  async function getUserData() {
    await fetch("http://ip-api.com/json")
      .then((res) => res.json())
      .then((data) => {
        setUserPlace({
          country: data.country,
          city: data.city,
        });
        console.log(data);
      })
      .catch((err) => console.log(err));
  }

  async function getLocalWeather() {
    await fetch(
      `https://api.openweathermap.org/data/2.5/weather?q=${userPlace.city}&appid=${APP_KEY}`
    )
      .then((res) => res.json())
      .then((data) => {
        setLocalWeather({
          temperature: Math.round(data.main.temp - 273.15),
        });
      })
      .catch((err) => console.log(err));
  }

  useEffect(() => {
    getUserData();
    getLocalWeather();
  });

  return (
    <div>
      <h3>
        Your current place is: {userPlace.country}, {userPlace.city}
      </h3>
      {localWeather.temperature ? (
        <h4>Temperature in your city is: {localWeather.temperature} &#8451;</h4>
      ) : null}
    </div>
  );
};

当我尝试将 [] 添加到我的 useEffect 时,eslint 会自动将其更改为:

 useEffect(() => {
    getUserData();
    getLocalWeather();
  }, [getLocalWeather]);

我应该怎么做才能只在第一次渲染时调用我的两个函数?

感谢您的帮助!

【问题讨论】:

    标签: reactjs react-hooks use-effect


    【解决方案1】:

    您可以使用空依赖项定义useEffect,这将确保函数只运行一次

    useEffect(() => {
        getUserData();
        getLocalWeather();
      }, []);
    

    但是当你像上面那样写它时,eslint 会抱怨依赖。因此,您可以禁用警告,例如

    useEffect(() => {
        getUserData();
        getLocalWeather();
        // eslint-disable-next-line react-hooks/exhaustive-deps
      }, []);
    

    在这篇文章中了解更多信息:How to fix missing dependency warning when using useEffect React Hook?

    否则,如果函数 getUserData 和 getLocalWeather 只能在 useEffect 中使用,那么您可以在 useEffect 中声明它们

    useEffect(() => {
        async function getUserData() {
            await fetch("http://ip-api.com/json")
              .then((res) => res.json())
              .then((data) => {
                setUserPlace({
                  country: data.country,
                  city: data.city,
                });
                console.log(data);
              })
              .catch((err) => console.log(err));
          }
    
          async function getLocalWeather() {
            await fetch(
              `https://api.openweathermap.org/data/2.5/weather?q=${userPlace.city}&appid=${APP_KEY}`
            )
              .then((res) => res.json())
              .then((data) => {
                setLocalWeather({
                  temperature: Math.round(data.main.temp - 273.15),
                });
              })
              .catch((err) => console.log(err));
          }
    
          getUserData();
          getLocalWeather();
      }, []);
    

    但是,如果由于某种原因您也想在 useEffect 之外使用它们并且不想禁用警告,则可以将 useCallback 用于函数并将它们添加为依赖项

     const getUserData = useCallback(async function() {
      await fetch("http://ip-api.com/json")
        .then((res) => res.json())
        .then((data) => {
          setUserPlace({
            country: data.country,
            city: data.city,
          });
          console.log(data);
        })
        .catch((err) => console.log(err));
    }, []);
    
    const getLocalWeather = useCallback(async function getLocalWeather() {
        await fetch(
          `https://api.openweathermap.org/data/2.5/weather?q=${userPlace.city}&appid=${APP_KEY}`
        )
        .then((res) => res.json())
        .then((data) => {
          setLocalWeather({
            temperature: Math.round(data.main.temp - 273.15),
          });
        })
        .catch((err) => console.log(err));
    }, []);
    
    
    useEffect(() => {     
      getUserData();
      getLocalWeather();
    }, [getUserData, getLocalWeather]);
    

    【讨论】:

    • @Treycos,还有第三种解决方案。取决于用例:-)
    • 当我们想要在不同的事件中进行 API 调用时使用第三种方法,例如加载时获取、一些用户输入后获取、页面更改获取等
    猜你喜欢
    • 2022-12-16
    • 2022-07-28
    • 2011-09-16
    • 2017-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    相关资源
    最近更新 更多