【发布时间】:2021-06-07 09:40:52
【问题描述】:
我正在尝试使用 Firebase 创建多人游戏并做出反应。 这是我目前得到的:
玩家可以输入他的名字并在“GameLobbies”集合中创建一个大厅文档。
他进入的页面包含一个新生成的代码,他可以与朋友分享。它还包含大厅内的玩家列表。
这是玩家 1 进入大厅后看到的内容(也是 firebase): first player entered
如您所见,一切都按预期进行
如果我现在通过 firebase 添加一个新玩家,会发生一些奇怪的事情:导致重新渲染,但它不会在我的 ul 标签中添加第二个玩家
这是玩家 1 在玩家 2 进入时看到的内容: second player entered
很奇怪,但是当玩家 3(以及之后的每个玩家)加入时,它变得更加陌生。 在玩家 2 之后加入的每个玩家都不会导致重新渲染。
这是玩家 1 在玩家 3 进入时看到的内容: third+ player entered
谁能帮我解决这个问题?英语不是我的母语,所以我希望这些图片能帮助说明我的问题。
这是整个页面的代码
import Style from './NewLobby.module.css'
import React, { useEffect, useState } from "react";
import { useLocation } from 'react-router-dom';
import { db } from "../services/firestore";
import { v4 } from 'uuid'
const NewLobby = () => {
const [players, setPlayers] = useState([]);
const [lobby, setLobby] = useState({});
const location = useLocation();
const currentUserId = v4();
const lobbiesRef = db.collection("GameLobbies");
useEffect(() => {
if (location.state.objective === "createLobby") {
console.log('create lobby')
createLobbyInDatabase();
} else if (location.state.objective === "joinLobby") {
console.log('join lobby')
findLobbyByCode();
}
}, [])
const createLobbyInDatabase = () => {
// getting lobby data
const code = createLobbyCode();
const lobbyId = v4();
// creating lobby in firebase
lobbiesRef.doc(lobbyId).set({
code: code,
id: lobbyId,
})
// creating players collection in lobby doc and assign current user
lobbiesRef.doc(lobbyId).collection("players").doc(currentUserId).set({
name: location.state.username,
score: 0,
id: currentUserId
})
// get lobby
lobbiesRef.doc(lobbyId).get().then(doc => {
setLobby(doc.data());
})
// get real-time lobby players database
lobbiesRef.doc(lobbyId).collection("players").onSnapshot((snapshot) => {
const changes = snapshot.docChanges();
let playersArr = players;
changes.forEach(change => {
if (change.type == 'added') {
playersArr.push(change.doc.data());
}
})
console.log(playersArr);
setPlayers(playersArr);
})
}
const findLobbyByCode = () => {
// TODO
}
const createLobbyCode = () => {
const codeLength = 4;
const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let codeTemp = '';
for (let i = 0, n = charset.length; i < codeLength; ++i) {
codeTemp += charset.charAt(Math.floor(Math.random() * n))
}
return codeTemp
}
return (
<section className={Style.section}>
<p>Code: {lobby.code}</p>
<p>Players:</p>
<ul>
{console.log('render:', players)}
{players.map(player => {
console.log('players.map(player => player.name):', player.name);
return <li className={Style.li} key={player.id}>{player.name}</li>
})}
</ul>
</section>
);
};
export default NewLobby;
【问题讨论】:
标签: reactjs firebase google-cloud-firestore