So I'm kind of new in typescript and trying something out. I want to randomize X quantity of players betweent X quantity of teams/groups to play a game with.( react native ts mobile app)
Weird behavior (atleast for me) the for loop that I'm using to update the teams in a state array does runs twice because I can see it in the logs and if I save my VS code document the second update in the state array does occus, but ofcourse I want it right the first time.
const [groupsWPlayer, setGroupsWPlayers] = useState<{title: string; players:string[]}[]>([]);
const [groups, setGroups] = useState<string[]>(route.params?.groups);
const [players, setPlayers] = useState<string[]>(route.params?.players);
const AsignPlayersToGroupsAtRandom = () => {
setPlayers(arrayShuffle(players));
for(let i =0; i <= groups.length-1; i ){
console.log(i " / " groups.length);
console.log("Group = " groups[i]);
setGroupsWPlayers([...groupsWPlayer, {title:groups[i], players:players}])
}
}
{groupsWPlayer.map((group, index) => (
<View key={index}>
<Text> title = {group.title}</Text>
<Text>{group.players}</Text>
<Text>{groupsWPlayer.length}</Text>
</View>
LOGS / 0 / 2 LOG Group = Ok (group name) LOG 1 / 2 LOG Group = Niet oke (group name)
But it only renders the last group, not the first and the last, which i wanted to.
So for some reason the setGroupsWPlayers only runs once, doe somebody know why and cares to explain to me why? Even if it's a rookie mistake, i'm trying to learn. Thanks in advance
CodePudding user response:
The issue is due to setGroupsWPlayers
is not updating the actual groupsWPlayer
immediately. The update will happen only on next render, so basically only the last call from the loop of setGroupsWPlayers
is applied. ...groupsWPlayer
will always be the same here, so on first render in the for loop you will always get []
from it.
Add a temporal variable to store everything and call setGroupsWPlayers
only once, outside of the loop.
const AsignPlayersToGroupsAtRandom = () => {
setPlayers(arrayShuffle(players));
const tmp: { title: string; players: string[] }[] = [];
// or
// const tmp: { title: string; players: string[] }[] = [...groupsWPlayer];
for (let i = 0; i <= groups.length - 1; i ) {
console.log(i " / " groups.length);
console.log("Group = " groups[i]);
tmp.push({ title: groups[i], players: players });
}
setGroupsWPlayers(tmp);
};
Note: If you also expect players
to be updated immediately after setPlayers(arrayShuffle(players));
- that will not happen, it will be updated on the next render only.