你好,所以我在加载这个组件时遇到了这个组件的问题,我前后左右重新渲染多次 useEffect 符文中的代码多次我认为我有正确的清理,但我不明白为什么会发生这种情况,如果如果我只是使用 react router doom 导航并多次前后移动 useEffect 中的代码多次运行为什么?
const LobbyCreated = () => {
const domainName = "http://localhost:3000";
const { gameid } = useParams();
const [{ user, socket }, dispatch] = useStateValue();
const [avatarInfo, setAvatarInfo] = useState({});
const [copied, setCopied] = useState(false);
const [loading, setLoading] = useState(true);
const [isStarting, setIsStarting] = useState(false);
const [canStart, setCanStart] = useState(false);
useEffect(() => {
let isMounted = false;
if (!isMounted) {
console.log("mounted<<<<");
setLoading(false);
socket.on("gameStatus", (statusUpdate) => {
console.log(statusUpdate);
setIsStarting(statusUpdate);
});
socket.on("usersJoined", (users) => {
console.log(users);
Object.keys(users).map((item) => {
if (users[item].name === user && users[item].isCreator === true) {
setCanStart(true);
console.log("starting...");
} else return console.log("you can't do that");
});
setAvatarInfo(users);
});
}
return () => {
console.log("unmount");
socket.off("gameStatus", isStarting);
socket.off("usersJoined", avatarInfo);
isMounted = true;
setLoading(true);
};
}, [gameid]);
const handleClick = () => {
Object.keys(avatarInfo).map((item, index) => {
if (
avatarInfo[item].name == user &&
avatarInfo[item].isCreator === true
) {
setIsStarting(true);
var gameStarted = true;
socket.emit("gameStatus", gameStarted);
} else return console.log("you can't do that");
});
};
return (
<>
{loading === true ? (
<p>....loading</p>
) : (
<div
className={isStarting ? "" : "container"}
id={isStarting ? "" : "screenLobby"}
>
{isStarting ? (
<Redirect to={"/gamestarted/" + gameid} />
) : (
<div className="row lobbyContainer">
<div className="col-sm-12 col-md-6 col-lg-6 lobbySectionSettings">
<div className="title">Settings</div>
<div className="lobbySettings">
<div className="lobbySettingsName">Lobby</div>
<div className="lobbyContent">
<div className="containerSettings">
<div className="form-group">
<label>Runde</label>
<select
className="form-control"
style={
canStart === true
? { cursor: "pointer" }
: { cursor: "not-allowed" }
}
disabled={canStart === true ? false : true}
>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
<option>9</option>
<option>10</option>
</select>
</div>
<div className="form-group">
<label>Timp de raspuns</label>
<select
className="form-control"
style={
canStart === true
? { cursor: "pointer" }
: { cursor: "not-allowed" }
}
disabled={canStart === true ? false : true}
>
<option>30</option>
<option>40</option>
<option>50</option>
<option>60</option>
<option>70</option>
<option>80</option>
<option>90</option>
<option>100</option>
<option>110</option>
<option>120</option>
<option>130</option>
<option>140</option>
<option>150</option>
<option>160</option>
<option>170</option>
<option>180</option>
</select>
</div>
<div className="form-group">
<label>Limba</label>
<select
className="form-control"
style={
canStart === true
? { cursor: "pointer" }
: { cursor: "not-allowed" }
}
disabled={canStart === true ? false : true}
>
<option>Romania</option>
<option>English (soon)</option>
</select>
</div>
</div>
<div
className="lobbyContentButtons"
style={{ display: "flex" }}
>
<button
className="button btn btn-success"
id="buttonLobbyPlay"
onClick={handleClick}
style={
canStart === true
? { cursor: "pointer" }
: { cursor: "not-allowed" }
}
disabled={canStart === true ? false : true}
>
Start Game
</button>
{/* <button className="button btn btn-danger" id="buttonLobbyPlay">
Leave Lobby
</button> */}
</div>
</div>
</div>
</div>
<div className="col-sm-12 col-md-6 col-lg-6 lobbySection">
<div className="title">
{/* Jucatori in camera {Object.keys(avatarInfo).length}{" "} */}
Players {Object.keys(avatarInfo).length}
</div>
<div className="lobbySectionPlayers">
{Object.keys(avatarInfo).map((item, i) => {
const isMe =
avatarInfo[item].name === user ? (
<>
<div className="lobbyName">
{avatarInfo[item].name}
</div>
<div className="lobbyYou">You</div>
</>
) : (
<div className="lobbyName">{avatarInfo[item].name}</div>
);
return (
<div className="lobbyPlayer" key={uuidv4()}>
{avatarInfo[item].isCreator === true ? (
<div className="lobbyIsCreator">
<span role="img" aria-label="crow-emoticon">
?
</span>
</div>
) : (
""
)}
<div className="avatarContainer">
<Avatar
style={{
// pentru mobil sa ii fac o clasa la avatar nu inline style
maxWidth: 96,
maxHeight: 96,
display: "flex",
alignItems: "center",
}}
avatarStyle="Transparent"
topType={avatarInfo[item].avatar.topType}
accessoriesType={
avatarInfo[item].avatar.accessoriesType
}
hairColor={avatarInfo[item].avatar.hairColor}
facialHairType={
avatarInfo[item].avatar.facialHairType
}
facialHairColor={
avatarInfo[item].avatar.facialHairColor
}
clotheType={avatarInfo[item].avatar.clotheType}
clotheColor={avatarInfo[item].avatar.clotheColor}
eyeType={avatarInfo[item].avatar.eyeType}
eyebrowType="Default"
mouthType={avatarInfo[item].avatar.mouthType}
skinColor={avatarInfo[item].avatar.skinColor}
/>
{isMe}
</div>
</div>
);
})}
</div>
</div>
<div className={isStarting ? "" : "invite-container"}>
<div className="title">Invite your friends!</div>
<div className="invite-bar">
<div className="invite-input">
<input
readOnly
id="invite"
type="text"
value={`${domainName}/game/${gameid}`}
/>
<div className="invite-overlay">
Hover over me to see the invite link!
</div>
</div>
<CopyToClipboard
text={`${domainName}/game/${gameid}`}
onChange={() => setCopied(true)}
>
<button
className="button btn btn-warning"
id="inviteCopyButton"
>
{copied ? "Copied!" : "Copy"}
</button>
</CopyToClipboard>
</div>
</div>
</div>
)}
</div>
)}
</>
);
};
export default LobbyCreated;