Console.log(MyState) показывает полный массив, но Console.log(MyState.длина) дает 0

#javascript #reactjs

#javascript #reactjs

Вопрос:

Я новичок в React, работающий над проектом системы посещаемости.(Извините за весь плохой код)

Итак, у меня есть этот компонент с именем showData, и он получает некоторые реквизиты от своего родительского компонента. В этом я использую условный рендеринг. Итак, у меня есть только одна переменная состояния с именем filteredUsers, и она инициализируется в пустой массив.

Теперь я хочу получить все пользовательские данные из firebase, и как только у меня будут все пользователи, я установлю свое состояние равным этому. Итак, для этого у меня есть useEffect(), который имеет эту асинхронную функцию, вызываемую init()

Теперь проблема в том, что, когда я пытаюсь использовать filteredUsers.length в части условного рендеринга, он дает мне 0.

 import React from "react";
import { db } from "./firebase";
import { dateStripper, getDaysArray } from "./utils";
import "./ShowData.css";
import MusterUser from "./MusterUser";

function ShowData(props) {
  let { userid, date, format, employee } = props;

  let [filteredUsers, setFilteredUsers] = React.useState([]);

  console.log(date);

  React.useEffect(() => {
    console.log("UseEffect triggered");

    async function getUserData(employeeID, currentDate) {
      let attendanceDoc = await db
        .collection(userid)
        .doc("Att-Records")
        .collection(currentDate)
        .doc(employeeID)
        .get()
        .then((doc) => {
          if (!doc.exists) {
            return { data: null, currentDate: currentDate };
          }
          return { data: doc.data(), currentDate: currentDate };
        });

      return attendanceDoc;
    }

    async function getEmployees() {
      return await db
        .collection(userid)
        .doc("Employee-Records")
        .collection("UUID-Data")
        .get()
        .then((employeeSnapshot) => {
          let temp = [];
          employeeSnapshot.forEach((employeeDoc) => {
            temp.push(employeeDoc);
          });
          return temp;
        });
    }

    async function init() {
      let allDates = [];
      let musterUsers = [];
      let dates = getDaysArray(date[0], date[1]);
      if (date[0] === date[1]) {
        dates.pop();
      }
      dates.forEach((date) => {
        allDates.push(dateStripper(date));
      });
      if (format === "muster" amp;amp; employee === "all") {
        let serialNum = 0;

        let users = await getEmployees();

        users.forEach(async (user) => {
          serialNum = serialNum   1;

          let tempUser = {
            SNo: serialNum,
            name: user.data()["Employee Name"],
            dept: user.data()["Employee Department"],
            desg: user.data()["Employee Designation"],
            total: 0,
            present: 0,
            absent: 0,
            miss: 0,
          };
          let calls = [];

          allDates.forEach(async (date) => {
            calls.push(getUserData(user.id, date));
          });

          let userPerDates = await Promise.all(calls);

          userPerDates.forEach((callbackResult) => {
            let data = callbackResult.data;
            let currentDate = callbackResult.currentDate;
            if (data) {
              tempUser["total"] = tempUser["total"]   1;
              if (data["Status"] === "A") {
                tempUser[currentDate] = "Absent";
                tempUser["absent"] = tempUser["absent"]   1;
              } else if (data["Status"] === "P") {
                tempUser[currentDate] = "Present";
                tempUser["present"] = tempUser["present"]   1;
              } else if (data["Status"] === "MIS") {
                tempUser[currentDate] = "MIS";
                tempUser["miss"] = tempUser["miss"]   1;
              }
            } else {
              tempUser[currentDate] = "N/A";
            }
          });
          musterUsers.push(tempUser);
        });
        return musterUsers;
      }
    }

    if (date.length) {
      console.log("init triggered");
      init().then((musterUsers) => {
        setFilteredUsers(musterUsers);
      });
    } else {
      console.log("not triggered");
    }
  }, [date, format, employee]);

  if (!date.length) {
    console.log("NoDate");
    return (
      <div className="noData">
        <h1>Nothing to show</h1>
      </div>
    );
  } else {
    console.log(filteredUsers);
    console.log(format);
    let allDates = [];
    let dates = getDaysArray(date[0], date[1]);
    if (date[0] === date[1]) {
      dates.pop();
    }
    dates.forEach((date) => {
      allDates.push(dateStripper(date));
    });
    console.log("I reached here");
    console.log(filteredUsers.length);
    if (format === "muster" amp;amp; filteredUsers.length > 0) {
      console.log("Main function runs");
      return (
        <div className="data">
          <div className="data__header">
            <h1>Muster Roll</h1>
            <h1>
              From {allDates[0]} to {allDates[allDates.length - 1]}
            </h1>
          </div>
          <div className="data__box">
            <div className="data__columns">
              <li>Employee Name</li>
              <li>Employee Department</li>
              <li>Employee Designation</li>
              {allDates.map((allDates) => (
                <li className="dateColumn">{allDates}</li>
              ))}
              <li>Total</li>
              <li>Present</li>
              <li>Absent</li>
              <li>Miss</li>
            </div>
            <div className="muster__users">
              <MusterUser user={filteredUsers} />
            </div>
          </div>
        </div>
      );
    } else {
      return <h1>OOPS</h1>;
    }
  }
}

export default ShowData;  

См. Массив содержит эти 3 элемента, но он по-прежнему дает длину 0, я действительно смущен тем, что происходит.)

Комментарии:

1. Прочитайте это reactjs.org/docs/hooks-state.html

Ответ №1:

Обратитесь к использованию перехвата состояния

 const [myState, setMyState] = React.useState([]);

...

newArray = ["Hello", "World", "Know"]
setMyState(newArray)

...

React.useEffect(() => {
  console.log(myState)
}, [ myState ])
  
   ...
  return 
    (<div>
       {!date.length ? 
          <div className="noData">
            <h1>Nothing to show</h1>
          </div> :
          <div>
           ....
          </div>
       }
    </div>)
  

Комментарии:

1. Я пробовал это раньше, но проблема, с которой я сталкивался, заключалась в том, что всякий раз, когда я делал console.log(MyState. длина), это дает мне 0, что действительно странно.

2. вы не можете получить MyState сразу после setMyState . вместо этого вам нужно получить его с помощью useEffect

3. Я имею в виду, что console.log(MyState) выводит правильный массив, но MyState . длина показывает 0.

4. Нет, дело в том, что я устанавливаю свое состояние в useEffect , а затем, когда оно отображается, я консолью. регистрируйте две вещи, массив состояния и его длину, массив состояния отображается нормально, но его длина дает мне 0, а не фактическую длину.

5. можете ли вы обновить свой вопрос со всей кодовой базой?

Ответ №2:

вместо того, чтобы помещать элементы один за другим в массив, просто используйте временный массив и обновляйте его любое количество раз, которое вы хотите, а затем, наконец, сделайте свое состояние равным этому массиву.