I have been working with React Hooks for a while, but the biggest problem for me is working with arrays.
I am making a register form for teams. Teams have players (array of strings).
The user should be able to add a team, and for each team, an input is shown with the current members in the team displayed above the input.
My question: How do I set the state of a nested array with React Hooks?
On the button click, it should (for now) add a string to the players array of the current team.
My Code:
JavaScript
x
32
32
1
interface ITeam {
2
id: string;
3
players: Array<string>;
4
}
5
6
7
export default function Team() {
8
const [teams, setTeams] = useState<Array<ITeam>>([{id: '1', players: ['a', 'b']}]);
9
10
return (
11
<div>
12
{teams.map((team, teamIndex) => {
13
return (
14
<div key={teamIndex}>
15
<h2>Team {teamIndex + 1}</h2>
16
<ul>
17
{team.players.map((player, playerIndex) => {
18
return (
19
<div key={playerIndex}>
20
{player}
21
</div>
22
);
23
})}
24
</ul>
25
<button onClick={() => setTeams([teams, team.players.concat('c')])}>Add player</button>
26
</div>
27
);
28
})}
29
</div>
30
);
31
}
32
Advertisement
Answer
You need to make use of team index and update that particular teams value using spread syntax and slice like
JavaScript
1
6
1
function addPlayer(index) {
2
setTeams(prevTeams => {
3
return [ prevTeams.slice(0, index), {prevTeams[index], players: [prevTeams[index].players, "c"] }, prevTeams.slice(index+1)];
4
});
5
}
6
or better you can just use map to update
JavaScript
1
12
12
1
function addPlayer(index) {
2
setTeams(prevTeams => {
3
return prevTeam.map((team, idx) => {
4
if(index === idx) {
5
return {prevTeams[index], players: [prevTeams[index].players, "c"]}
6
} else {
7
return team;
8
}
9
})
10
});
11
}
12
JavaScript
1
31
31
1
const { useState } = React;
2
3
function Team() {
4
const [teams, setTeams] = useState([{ id: "1", players: ["a", "b"] }]);
5
6
function addPlayer(index) {
7
setTeams(prevTeams => {
8
return [ prevTeams.slice(0, index), {prevTeams[index], players: [prevTeams[index].players, "c"] }, prevTeams.slice(index+1)];
9
});
10
}
11
12
return (
13
<div>
14
{teams.map((team, teamIndex) => {
15
return (
16
<div key={teamIndex}>
17
<h2>Team {teamIndex + 1}</h2>
18
<ul>
19
{team.players.map((player, playerIndex) => {
20
return <div key={playerIndex}>{player}</div>;
21
})}
22
</ul>
23
<button onClick={() => addPlayer(teamIndex)}>Add player</button>
24
</div>
25
);
26
})}
27
</div>
28
);
29
}
30
31
ReactDOM.render(<Team />, document.getElementById("root"));
JavaScript
1
4
1
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
2
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
3
4
<div id="root"></div>