【发布时间】:2022-01-08 15:20:15
【问题描述】:
在从 Firebase 数据库检索数据后,我在 React 中使用 useState 挂钩存储和访问数据时遇到问题。问题似乎源于并非所有用户都拥有playerData数据包中的所有值——在这种情况下,如果玩家有“先锋”成就,他们可以创建一个解决方案,如果没有,他们只能设置他们的个人资料名称(然后在playerData 中有一个未定义的settlementName)。如果帐户有所有相关数据,它工作正常,但如果没有,那么它会遇到一堆空值的 TypeErrors。
谁能告诉我我在这里做错了什么?我想知道我是否应该使用NoPioneer()(如果用户被确定为没有先驱成就时执行)将空值填充到playerData 对象中,这样它至少不会命中对象中的空引用。
此外,我发现如果我删除了组件渲染的playerData.settlement.settlementName 渲染引用(根据玩家的先驱状态可能存在或不存在的数据)。所以,这让我觉得我可能需要在渲染调用中添加一个条件来检查数据是否存在(但遗憾的是我不确定如何执行此操作)。
这是我的 React 组件供参考:
function Dashboard() {
const [ error, setError ] = useState('');
const history = useHistory();
const pioneer_emails = Firebase.database().ref("pioneer_emails");
const player_achievements = Firebase.database().ref("players/" + currentUser.uid + "/achievements");
const [ pioneer, setPioneer ] = useState(false);
const [ playerData, setPlayerData ] = useState({
player_data: {
playerName: "",
},
settlement: {
settlementName: "",
}
});
const playerName = playerData.player_data.playerName;
const settlementName = playerData.settlement.settlementName;
var dateVariable = Date().toLocaleString()
async function CheckForPioneer(){
//check if email is on pioneer list
await pioneer_emails.on('value', gotEmail, errData);
//if not, then check if the player has the achievement already
if(!pioneer) {
player_achievements.on('value', gotAchievement, noPioneer);
}
}
//check to see if the player's email is on the pioneer list
function gotEmail(data){
//console.log(data.val())
var emails = data.val();
var keys = Object.keys(emails);
for(var i = 0; i < keys.length; i++){
let k = keys[i];
if(emails[k] === currentUser.email){
//set bool
setPioneer(true);
//add achievement to database
SetPioneerAchievement();
//delete email from database
pioneer_emails.child(k).remove();
}
}
}
//check to see if the player has the pioneer achievement
function gotAchievement(data){
var achievements = data.val();
var achievementKeys = Object.keys(achievements);
for(var i = 0; i < achievementKeys.length; i++){
if(achievementKeys[i] === "MISC001"){
setPioneer(true);
console.log("We got a pioneer, baby!");
}
}
}
function noPioneer(){
console.log('Player is not a pioneer!');
}
function errData(err){
console.log('Error!');
console.log(err)
}
function GetPlayerData(){
Firebase.database().ref().child("players").child(currentUser.uid).get().then((snapshot) => {
if (snapshot.exists()) {
setPlayerData(snapshot.val());
console.log(snapshot.val());
console.log(playerData);
console.log(playerData.player_data.playerName);
console.log(playerData.settlement.settlementName);
} else {
console.log("No data available");
}
}).catch((error) => {
console.error(error);
});
}
function SetPioneerAchievement(){
const achievement = {
"MISC001": {
name: "Kickstarter Pioneer",
completed: dateVariable
}
}
player_achievements.set(achievement).catch(alert);
console.log('Achievement added: ' + achievement.name)
}
useEffect(() => {
GetPlayerData();
CheckForPioneer();
}, []);
return (
<div className="dashboard">
<div className="dashboard-box">
<div className="dashboard-content">
<h1>DASHBOARD</h1>
<br /><alert>{error}</alert>
<br />
<center><h3>Name:</h3></center>
<center><h2>Ancestor {playerData && playerData.player_data.playerName}</h2></center>
<center>{pioneer ? <h3 className="pioneer-tag">Pioneer from the 2021 Kickstarter Campaign</h3> : null }</center>
<br /><br />
{ pioneer ? (
<div><center><h3>Founder of the:</h3></center>
<center><h2>{playerData && playerData.settlement.settlementName} Settlement</h2></center></div>
)
: null }
<center><Link to="/update-dashboard" className="link"><input type="submit" id="ancestor-signup-submit" name="dashboard-update-details" value="Update Details" /></Link></center>
<br />
<div class="footer-switch-login">
<center><Link to="/" onClick={handleLogout} className="link">Log out.</Link></center>
</div>
</div>
</div>
</div>
);
}
export default Dashboard;
任何帮助将不胜感激,因为我不知所措。谢谢!
【问题讨论】:
标签: javascript reactjs firebase firebase-realtime-database use-state