我已经使用了 React 组件,如果我控制对象,它会在其中显示对象键值。但是如果我在组件中访问它
undefined
.
我已经像这样初始化了对象,
let faeko = new Faeko({}, client)
用户登录后,
faeko
对象更新为occupants
。它显示在控制台中,因为 Javascript 在记录值中的实时更新。
我使用 useEffect 和 setTimeout 来添加延迟以更新组件中的值。但它不是。
这是我的
GameFrame.jsx
。它记录了居住者的价值。如果它显示出来,那么它应该在 DOM 中渲染居住者。但它不是。
import React, { useEffect, useState } from "react";
export const GameFrame = (props) => {
console.log("TEST FAEKO ", props.game.data);
const [start, setStart] = useState({});
let timer;
useEffect(() => {
console.log("tested", props.game);
console.log("Props.game", props.game.data);
clearTimeout(timer);
timer = setTimeout(() => {
console.log("props gets updated!", props.game.data.occupants);
setStart(props.game.data);
}, 1000);
}, [props.game.data]);
return (
<div>
{/* {console.log("start ", start)} */}
{start.occupants !== undefined && start.occupants.length > 0 && (
// console.log("here updated", start.occupants) &&
<div>Occupants</div>
)}
</div>
);
};
我该怎么办,它在单个选项卡中工作。如果我需要在我创建的房间中加入第二个用户,它不会呈现。可以解决吗?
如果你想参加谷歌会议,请问我! 我在这浪费了5天……
根据您的代码和描述,问题似乎与
props.game
对象更新的异步性质有关。当您在 props.game.data
挂钩中记录 useEffect
时,您可能会看到更新后的值,因为它会在更新后立即记录该值。但是,当您尝试在 return 语句中访问依赖于 props.game.data
的起始状态变量时,它可能仍然具有初始值,因为状态更新可能尚未发生。
解决此问题的一种方法是在返回语句中添加条件检查,以便仅在开始状态变量已使用新的
props.game.data
值更新时才呈现组件。
带有此检查的代码的更新版本:
import React, { useEffect, useState } from "react";
export const GameFrame = (props) => {
console.log("TEST FAEKO ", props.game.data);
const [start, setStart] = useState({});
useEffect(() => {
console.log("tested", props.game);
console.log("Props.game", props.game.data);
const timer = setTimeout(() => {
console.log("props gets updated!", props.game.data.occupants);
setStart(props.game.data);
}, 1000);
return () => clearTimeout(timer); // clear the timeout on component unmount
}, [props.game.data]);
if (!Object.keys(start).length) { // check if start object is empty
return null; // return null until it gets updated
}
return (
<div>
{start.occupants && start.occupants.length > 0 && (
<div>Occupants</div>
)}
</div>
);
};
这段代码中,return语句中的if语句检查起始对象是否不为空。如果为空,则返回 null 以不呈现任何内容。一旦起始对象更新为新的
props.game.data
值,组件将使用更新后的值重新渲染。
另请注意,我将定时器声明移到了
useEffect
钩子中以避免多个定时器同时运行的潜在问题,并添加了一个清除函数以清除组件卸载时的超时。
看起来您正在尝试使用 props.game.data 更改 gamestate 组件,但是如果 props.game.data 对象在 GameFrame 之外更新,则对象作为参考传递,它不会重新渲染,所以这就是我建议使用的原因useeffect 以便您可以将唯一标识符作为道具传递给 GameFrame 组件
import React, { useEffect, useState } from "react";
export const GameFrame = (props) => {
console.log("TEST FAEKO ", props.game.data);
const [start, setStart] = useState({});
let timer;
useEffect(() => {
console.log("tested", props.game);
console.log("Props.game", props.game.data);
clearTimeout(timer);
timer = setTimeout(() => {
console.log("props gets updated!", props.game.data.occupants);
setStart(props.game.data);
}, 1000);
}, [props.identifier]);
return (
<div>
{/* {console.log("start ", start)} */}
{start.occupants !== undefined && start.occupants.length > 0 && (
// console.log("here updated", start.occupants) &&
<div>Occupants</div>
)}
</div>
);
};
<GameFrame game={game} identifier={game.data.occupants.length} />
我建议将这个识别道具用于游戏框架