useEffect第一次中断useState的数组

问题描述

我正在学习反应钩子。我正在模拟数据js调用“ MockFireBase.js”,如下所示:

const userIngredientsList = [];
export const Get = () => {
    return userIngredientsList;
}
export const Post = (ingredient) => {
    ingredient.id = userIngredientsList.length + 1;
    userIngredientsList.push(ingredient);
    return ingredient;
}

然后我的react hooks组件“ Ingredients.js”将调用此模拟实用程序,如下所示:

const Ingredients = () => {
  const [userIngredients,setUserIngredients] = useState([]);
  
  // only load one time
  useEffect(() => { setUserIngredients(Get()); },[]);
  
  const addIngredienHandler = ingredient => {
    let responsData = Post(ingredient);
    setUserIngredients(preIngredients => {
      return [...preIngredients,responsData]
    });
  }
  
  return (
    <div className="App">
      <IngredientForm onAddIngredient={addIngredienHandler} />
      <section>
        <IngredientList ingredients={userIngredients} />
      </section>
    </div>
  );
  )
} 

当我添加第一个成分时,它添加了两个成分(当然,我在console.log中得到了相同的关键问题)。然后我添加了第二种成分就可以了。

如果我按如下所示删除useEffect代码,它将很好用。

// only load one time
useEffect(() => { setUserIngredients(loadedIngredients); },[]);

我想知道如果我使用useEffect,我在上面做错了什么

解决方法

该问题不在useEffect中。这是关于更改全局userIngredientsList数组。

  1. 通过useEffect将初始组件状态设置为userIngredientsList
  2. 然后在addIngredienHandler内致电Post()。此功能有两件事: 2a。将新成分推入全局userIngredientsList数组`。由于它与您在步骤1中保存在状态中的实例相同,因此您的状态现在已经包含此成分。 2a。返回此成分
  3. 然后,addIngredienHandler再次将此成分添加到状态中-因此您最终两次将其置于状态中。

修复1 userIngredientsList.push(ingredient);函数中删除Post行。

修复2 或者,如果您需要此成分的全局列表以备将来使用,则应确保不要将其直接存储在组件状态中,而应在您的状态中创建浅表副本:

useEffect(() => { setUserIngredients([...Get()]); },[]);

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...