#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;
Комментарии:
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:
вместо того, чтобы помещать элементы один за другим в массив, просто используйте временный массив и обновляйте его любое количество раз, которое вы хотите, а затем, наконец, сделайте свое состояние равным этому массиву.