# #javascript #reactjs #firebase #google-cloud-firestore #frontend
Вопрос:
Я создаю лобби для игры и хочу отобразить список игроков. Я наблюдаю за новыми игроками в комнате.
const [roomUsers, setRoomUsers] = useState([])
useEffect(() => {
if (room)
DB.collection("room_users").where("room_id", "==", room.id)
.onSnapshot((querySnapshot) => {
const newRoomUsers = [];
querySnapshot.forEach((doc) => {
newRoomUsers.push(doc.data());
});
setRoomUsers(newRoomUsers)
});
})
Когда я присоединяюсь во втором окне, количество игроков меняется, но список обновляется с течением времени. Когда я присоединяюсь больше раз, список вообще перестает обновляться.
<h4>Players list ({roomUsers.length}/4)</h4>
{roomUsers.map(roomUser => (
<PlayerListItem
roomUser={roomUser}
owner={roomUser.uuid === room.owner}
/>
))}
В компоненте PlayerListItem я выбираю пользователя через uuid
const [user, setUser] = useState(null)
useEffect(() => {
DB.collection('users').where('uuid', '==', roomUser.uuid).get().then(snapshot => {
if (!snapshot.empty)
setUser(snapshot.docs[0].data())
})
}, [])
Затем я возвращаю имя пользователя через компонент.
Иногда одно и то же имя пользователя появляется в списке дважды вместо разных
Комментарии:
1. Есть ли у вас переменная room в зависимости от вашего первого эффекта использования?
Ответ №1:
В вашем эффекте использования отсутствует массив зависимостей. Он также должен возвращать функцию очистки
useEffect(() => {
if (!room) {
return;
}
const unsub = DB.collection("room_users").where("room_id", "==", room.id)
.onSnapshot((querySnapshot) => {
const newRoomUsers = [];
querySnapshot.forEach((doc) => {
newRoomUsers.push(doc.data());
});
setRoomUsers((currVal) => {
console.log({currVal, newRoomUsers})
const newVal = [] // change this to be correct
return newVal
})
});
return () => unsub();
}, [room])
Комментарии:
1. Спасибо, это работает, но теперь массив roomUsers не всегда обновляется правильно, когда пользователь покидает комнату, неправильный исчезает из списка. Как будто он просто смотрел на номер индекса.
2. Хорошо, я изменил setRoomUsers на синтаксис обратного вызова (что означает, что react теперь предоставит нам currVal). Я надеюсь, что журнал консоли даст вам некоторые подсказки о том, как вы можете приступить к подготовке newVal