React 函数在第一次调用时不起作用,但每隔一次就起作用

React function not working on first call, but works every other time

我确定这是一个非常简单的问题,但我尝试了很多不同的方法,但我只会让事情变得更糟。我正在构建一个包含总卡路里的营养应用程序。它应该根据 api 调用的卡路里计算总卡路里,并且在第二次后效果很好。但是第一次显示0

营养成分

const [search, setSearch] = useState("");
  const [isLoaded, setIsLoaded] = useState(false);
  const [foodId, setFoodId] = useState("");
  const [foodList, setFoodList] = useState([]);
  const [totalCal, setTotalCal] = useState(0);

  const addCal = (cal, totalCal) => {
    const total = cal + totalCal;
    setTotalCal(total);
  };

  // Getting user input for an argument to be used later in API call
  const getInput = e => {
    e.preventDefault();
    setSearch(e.target.value);
  };

  // Submitting user input / starting API call / setting food to be searched
  const handleSubmit = e => {
    e.preventDefault();
    setIsLoaded(true);
    // console.log(list);
  };

  // Function that holds API call using form input
  const getNutrition = food => {
    const appId = "e124e5bc";
    const appKey = "fd3e0319818416b4e8496e3502bcb565";
    fetch(
      `https://api.nutritionix.com/v1_1/search/${food}?&appId=${appId}&appKey=${appKey}`
    )
      .then(response => {
        return response.json();
      })
      .then(responseData => {
        let foodId = responseData.hits[0].fields.item_id;
        fetch(
          `https://api.nutritionix.com/v1_1/item?id=${foodId}&appId=${appId}&appKey=${appKey}`
        )
          .then(response => {
            return response.json();
          })
          .then(responseData => {
            setFoodId(foodId);
            const foodObject = {
              calories: responseData.nf_calories,
              protein: responseData.nf_protein,
              food: responseData.item_name,
              key: foodId,
              totalCal: totalCal
            };
            addCal(foodObject.calories, totalCal);
            setFoodList([...foodList, foodObject]);
            setIsLoaded(false);
          });
      });
    console.log(isLoaded);
  };

  // Calling nutrition function that holds API
  useEffect(() => {
    if (isLoaded) {
      getNutrition(search);
      setFoodId(foodId);
    }
    // eslint-disable-next-line
  }, [isLoaded]);

  return (
    <div className={styles.nutritionContainer}>
      <FoodForm submit={handleSubmit} input={getInput} />
      <table className={styles.center}>
        <thead>
          <tr>
            <th>Food Item</th>
            <th>Calories</th>
            <th>Protein</th>
            <th>Total Calories</th>
            <th>Total Protein</th>
          </tr>
        </thead>
        <tbody>
          <TableList foodList={foodList} />
        </tbody>
      </table>
    </div>
  );
};

export default Nutrition;


包含来自 api 营养成分调用的动态 table 数据的列表

const TableList = ({ foodList }) => {
  return foodList.map(item => (
    <tr key={item.key}>
      <td>{item.food}</td>
      <td>{item.calories}</td>
      <td>{item.protein}</td>
      <td>{item.totalCal}</td>
    </tr>
  ));
};

export default TableList;

因为 isLoaded 最初设置为 false,因此它不会在 useEffect

中调用 getNutrition(search); setFoodId(foodId);

我不能确定为什么你的第一个 api 电话打不通,但当晚我有一些建议可以帮助你。

首先,我根本不会使用 useEffect 挂钩。它不必要地使您的代码复杂化。您只需要在每次提交表单时调用 api 那么为什么不这样做呢?而不是更改 is loaded 值等。这样做之后您可能会发现错误消失了,或者至少会更容易理解代码中发生的事情。

我要做的另一件事是从状态中删除 totalCals。相反,我每次都会计算它,除非你有成千上万的物品,否则它真的不会成为性能问题。这样做的好处是您的代码将更容易理解,如果您说问题是卡路里没有更新,这应该可以解决它。这也意味着您的状态没有非规范化。如果你每次都计算它然后从数组中删除一个项目,你就不用担心忘记也减少总数等

祝你好运!!

我认为您的代码在再次重用相同变量名时存在一些问题,请检查我修复的以下代码。当您使用 isLoaded 值作为默认值时,将搜索值添加到默认值。

希望对您有所帮助。但是现在,你的 api 限制已经结束,因为我测试了很多。 :P

修复 1

useEffect(() => {
if (isLoaded) {
  getNutrition(search);
}}, [isLoaded]);

修复 2

const getNutrition (food)=> {
 const appId = "e124e5bc";
 const appKey = "fd3e0319818416b4e8496e3502bcb565";
 fetch(
  `https://api.nutritionix.com/v1_1/search/${food}?&appId=${appId}&appKey=${appKey}`
 )
  .then(response => {
    return response.json();
  })
  .then(responseData => {
    let fId = responseData.hits[0].fields.item_id;
    setFoodId(fId);

    fetch(
      `https://api.nutritionix.com/v1_1/item?id=${fId}&appId=${appId}&appKey=${appKey}`
    )
      .then(response => {
        return response.json();
      })
      .then(responseData => {
        console.log("DATA", responseData);
        const foodObject = {
          calories: responseData.nf_calories,
          protein: responseData.nf_protein,
          food: responseData.item_name,
          key: foodId,
          totalCal: totalCal
        };
        addCal(foodObject.calories);
        setFoodList([...foodList, foodObject]);
        setIsLoaded(false);
      });
  });
console.log(isLoaded);};

修复 3

const addCal = cal => {
const total = cal + totalCal;
setTotalCal(total);};