简体   繁体   English

React.js 和 Firebase querySnapshot.forEach 用相同的对象替换数组

[英]React.js and Firebase querySnapshot.forEach replacing array with identical objects

I've been facing this issue for a couple of days where I have an array named tempTaskArray, which stores objects filled with data taken from my firestore database.几天来我一直面临这个问题,我有一个名为 tempTaskArray 的数组,它存储填充了从我的 firestore 数据库中获取的数据的对象。

These objects contain the correct data on each iteration of the.forEach method but when put into my state variable, "tasks" (an array), from array tempTaskArray, all objects contain the data of the last created object.这些对象在 .forEach 方法的每次迭代中包含正确的数据,但是当从数组 tempTaskArray 放入我的 state 变量“任务”(数组)时,所有对象都包含最后创建的 object 的数据。

This issue is not run into when I have an array of strings.当我有一个字符串数组时,不会遇到这个问题。

See code below:请参阅下面的代码:

      const getTasks = () => {
    db.collection("users").doc(uid).collection("tasks")
    .orderBy("epochdate", "asc")
    .get()
    .then((querySnapshot) => {
        querySnapshot.forEach((doc) => {

          // populates array with strings
          // tempTaskArray.push(doc.data().taskname)

          // tempTaskObject is an empty object
          tempTaskObject.taskname= doc.data().taskname
          tempTaskObject.duedate= doc.data().duedate

          // gets epoch date value and stores it
          var epochDate = doc.data().epochdate;

          // gets current time
          const day = new Date();
          let currentTime = day.getTime();

          // finds time remaining in epoch 
          var timeRemaining = epochDate - currentTime;

          // finds how many days are left and rounds down
          var daysLeft = (timeRemaining / 86400000)
          daysLeft = Math.floor(daysLeft)

          tempTaskObject.duein = daysLeft

          tempTaskArray.push(tempTaskObject)

        });
        setTasks(tempTaskArray)

    })
    .catch((error) => {
        console.log("Error getting documents: ", error);
    });
  }
  getTasks();

The data taken populating state variable "task" is then rendered in component Task seen below:填充 state 变量“任务”的数据随后在组件任务中呈现,如下所示:

    <div>
      {tasks.map((task) => (
      <Task
        key={task}
        task__title={task.taskname}
        due__date={task.duedate}
        days__away={task.duein}
      />
    ))}
    </div>

I would be extremely grateful for an explanation of why this is happening.如果能解释为什么会这样,我将不胜感激。 Thanks in advance提前致谢

Based on the provided code I believe it's an error of adding the reference of the tempTaskObject to the tempTaskArray and changing the same referenced object on each iteration.根据提供的代码,我认为将 tempTaskObject 的引用添加到 tempTaskArray 并在每次迭代中更改相同的引用 object 是错误的。

To avoid this you can reassign a new Object to tempTaskObject on every iteration, like为避免这种情况,您可以在每次迭代时将新的 Object 重新分配给 tempTaskObject,例如

.then((querySnapshot) => {
    querySnapshot.forEach((doc) => {

      // tempTaskObject is (now really) an empty object
      tempTaskObject = {};
      tempTaskObject.taskname= doc.data().taskname;

Further Explanation进一步说明

I believe it worked before with String types, because these are primitive datatypes which will just be copied into the tempTaskArray .我相信它以前适用于 String 类型,因为这些是原始数据类型,只会被复制到 tempTaskArray中。

The current tempTaskObject though has multiple properties (duein, taskname, duedate) and is therefore a complex object. When pushing objects to an javascript array, it adds the reference to the object to the array, NOT a copy .当前的 tempTaskObject 虽然有多个属性(duein、taskname、duedate),因此是一个复杂的 object。当将对象推送到 javascript 数组时,它会将对 object 的引用添加到数组,而不是副本 In your example you always keep the reference to the tempTaskObject and that's why it always changes the properties of the exact same object.在您的示例中,您始终保留对 tempTaskObject 的引用,这就是为什么它总是更改完全相同的 object 的属性。

Examples例子

 // Array with Primitives const animalNames = ['Tiger', 'Spider']; console.log('animalNames', animalNames); let scaryName = animalNames[1]; scaryName = 'Goldfish'; console.log('still scary animalNames', JSON.stringify(animalNames)); // nothing changed, because we're working with a copy

 // Array with Objects const animals = [{ name: 'Tiger', teeth: 30, legs: 4 }, { name: 'Spider', teeth: 0, legs: 8 }]; console.log('animals', animals); let scaryAnimal = animals[1]; // storing a reference to the spider object scaryAnimal.name = 'Goldfish'; scaryAnimal.legs = 0; console.log('less scary animals', animals); // spider got replaced by a goldfish // Now we'll want to add another animal the WRONG WAY // FIX: Uncomment line below to properly add a bunny // scaryAnimal = {}; scaryAnimal.name = 'Bunny'; scaryAnimal.legs = 4; scaryAnimal.teeth = 2; animals.push(scaryAnimal); console.log('duplicated animal', JSON.stringify(animals));

Edit: Fixed typo编辑:固定错字

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Firebase 类型错误:querySnapshot.forEach 在 React 中不是 function - Firebase TypeError: querySnapshot.forEach is not a function in React JavaScript 中的 Arrays 数组。替换 querySnapshot.forEach - Array of Arrays in JavaScript. Replacement for querySnapshot.forEach 如何在 React.js 中拆分 Firebase Firestore 数组中的数组项值 - How to Split Array Item Values in Firebase Firestore Array in React.js Firebase 无需在 querySnapshot 上运行 forEach 循环即可获取集合文档数据 - Firebase get collection document data without running a forEach loop on querySnapshot 在 React js 中更新 Firebase 实时数据库中的对象数组 - Updating Array of Objects in Firebase Realtime Database in React js Firebase react.js 应用已部署 - 空白页 - Firebase react.js app deployed - blank page 如何使用 React.js 从 firebase 获取嵌套文档 - How to fetch nested document from firebase using React.js 如何将这段 firebase 代码转换成它在 React.js 中的最新语法? - How to convert this firebase code into its latest syntax in React.js? QuerySnapshot 优化了 firebase - QuerySnapshot was optimized out firebase 如何使用 react.js 中的 WHERE 查询计算 Firebase Firestore 中集合中的文档数 - How To Count Number of Documents in a Collection in Firebase Firestore With a WHERE query in react.js
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM