In my useEffect I am populating two array each array there are two element. However, only one element in each array is showing on my page.
Here is the useEffect
useEffect(() => {
let tempArray = [...players];
if (secondTeam.length < Math.floor(Number(playersCount) / 2)) {
if (random) {
for (let i = 0; i < 4; i ) {
const num = Math.floor(Math.random() * tempArray.length);
if (i < Math.floor(Number(playersCount) / 2)) {
const tempFirstTeam = [...firstTeam];
tempFirstTeam.push(tempArray[num]);
setFirstTeam(tempFirstTeam);
} else {
const tempSecondTeam = [...secondTeam];
tempSecondTeam.push(tempArray[num]);
setSecondTeam(tempSecondTeam);
}
tempArray.splice(num, 1);
}
}
}
}, []);
Here is the entire jsx file
import { useState, useEffect } from "react";
import { registerGame } from "../features/game/gameSlice";
import { useSelector, useDispatch } from "react-redux";
import InputGroup from "react-bootstrap/InputGroup";
import { toast } from "react-toastify";
import PlayerImageAndName from "./PlayerImageAndName";
const vsStyle = {
position: "absolute",
top: "15%",
left: "50%",
transform: "translate(-50%, -50%)",
};
function PlayerSelection() {
const { playersCount, points, random, teamOne, teamTwo } = useSelector(
(state) => state.game.playerData
);
const dispatch = useDispatch();
const { players } = useSelector((state) => state.player);
const [firstTeam, setFirstTeam] = useState([]);
const [secondTeam, setSecondTeam] = useState([]);
const [playersChosen, setPlayersChosen] = useState(0);
useEffect(() => {
let tempArray = [...players];
if (secondTeam.length < Math.floor(Number(playersCount) / 2)) {
if (random) {
for (let i = 0; i < 4; i ) {
const num = Math.floor(Math.random() * tempArray.length);
if (i < Math.floor(Number(playersCount) / 2)) {
const tempFirstTeam = [...firstTeam];
tempFirstTeam.push(tempArray[num]);
setFirstTeam(tempFirstTeam);
} else {
const tempSecondTeam = [...secondTeam];
tempSecondTeam.push(tempArray[num]);
setSecondTeam(tempSecondTeam);
}
tempArray.splice(num, 1);
}
}
}
}, []);
return (
<div>
<div className="d-flex" style={{ height: "350px" }}>
<div className="p-2 flex-grow-1" style={{ display: "flex" }}>
{firstTeam.map((player) => (
<PlayerImageAndName key={player._id} player={player} />
))}
</div>
{secondTeam.length > 0 && (
<div className="p-2" style={vsStyle}>
<h1>Vs.</h1>
</div>
)}
<div className="p-2 flex-grow-1" style={{ display: "flex" }}>
{secondTeam.map((player) => (
<PlayerImageAndName key={player._id} player={player} />
))}
</div>
</div>
);
}
export default PlayerSelection;
CodePudding user response:
setFirstTeam does not update firstTeam instantly
The same is true for setSecondTeam as well. Let's take just the for loop and simplify it to make the problem more apparent:
for (let i = 0; i < 4; i ) {
const tempFirstTeam = [...firstTeam];
tempFirstTeam.push(tempArray[num]);
setFirstTeam(tempFirstTeam);
}
This loop will run 4 times and each time it happens firstTeam
has not changed and will always be []
. Therefore, tempFirstTeam
starts as an empty array and then has 1 thing pushed in to it.
So, instead, you need move both tempFirstTeam
and tempSecondTeam
outside your for loop, and set them once:
const tempFirstTeam = [...firstTeam];
const tempSecondTeam = [...secondTeam];
for (let i = 0; i < 4; i ) {
const num = Math.floor(Math.random() * tempArray.length);
if (i < Math.floor(Number(playersCount) / 2)) {
tempFirstTeam.push(tempArray[num]);
} else {
tempSecondTeam.push(tempArray[num]);
}
tempArray.splice(num, 1);
}
setFirstTeam(tempFirstTeam);
setSecondTeam(tempSecondTeam);