I am building a user flow to allow users to enter stats for a video game that they played. My react component renders an excel like table where they can manually type in the stats (like an excel spreadsheet where the y-axis is a column of players and the x-axis are the stats for each player.
When I update a particular stat for a particular player, every player's stat value for that particular stat is also changed. For example, if I update Player A with 5 goals every other player on the team will also have 5 goals. This shouldn't happen.
First, I initialize a matchStats object:
initializeMatchStats = (numGames) => {
const {matchInfo} = this.props;
const gameArray = new Array(numGames).fill('');
const matchStats = gameArray.map((game, i) => {
let statsWithKeys = {};
let gameInfo = {};
matchInfo.circuitStats.map(key => {
statsWithKeys[key.toLowerCase()] = 0
})
const players = new Array(matchInfo.playersAllowedInGame).fill({
stats: statsWithKeys
}).map(p => {
return {
...p,
dropdownOpen: false,
id: Math.random().toString(36)
}
})
gameInfo = {
players,
index: i + 1
}
return gameInfo
})
this.setState({matchStats, numGames, numGamesModalOpen: false, uploadManually: true}, () => console.log('matchStats: ', matchStats))
}
Then, I update the matchStats object as it is changed by the user:
updateStatsManually = (val, player, game, header, e) => {
e.preventDefault();
const {matchStats} = this.state;
// matchStats is an array of games in each match. A game is made up of the players (and their respective stats) in the game.
const { matchInfo } = this.props;
const gameToUpdate = matchStats.find(g => g.index === game.index)
let playerToUpdate = gameToUpdate.players.find(p => p.id === player.id)
let newStats = playerToUpdate.stats;
newStats[header] = val;
playerToUpdate.stats = newStats;
gameToUpdate.players = [...gameToUpdate.players.filter(p => p.id !== player.id), playerToUpdate]
this.setState({
matchStats: [...matchStats.filter(g => g.index !== game.index), gameToUpdate]
})
}
Here is the react code block:
<Section>
{matchStats.find(g => g.index === game).players.map((player, i) => <Row key={i}>
{!uploadManually && <Column>
<Input disabled style={{textAlign: 'center'}} placeholder={player.name} />
</Column>}
{circuitStats.map((header, i) => <Column key={`${i}-${player.id}`}>
<Input id={`${i}-${player.id}-${header}`} value={player.stats[header.toLowerCase()]} disabled={!uploadManually} onChange={(e) => updateStatsManually(e.target.value, player, currentGame, header.toLowerCase())} />
</Column>)}
</Row>)}
</Section>
I would expect that when I change an input value for one stat for a given player, it only changes the stat value for that particular player. However, it changes it for every player.
I've been messing with this for a while now and struggling to see what I'm doing wrong. I thought it might be related to how inputs are rendered in a .map function but I tried separating a test input and the result was the same. Any help is appreciated!