【发布时间】:2020-01-26 02:45:21
【问题描述】:
我正在构建一个用户流程,以允许用户输入他们玩过的视频游戏的统计数据。我的 react 组件呈现了一个类似 excel 的表格,他们可以在其中手动输入统计数据(就像一个 excel 电子表格,其中 y 轴是一列玩家,x 轴是每个玩家的统计数据。
当我更新特定玩家的特定统计数据时,每个玩家对该特定统计数据的统计值也会更改。例如,如果我将球员 A 更新为 5 个进球,那么球队中的每个其他球员也将有 5 个进球。这不应该发生。
首先,我初始化一个 matchStats 对象:
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))
}
然后,我更新用户更改的 matchStats 对象:
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]
})
}
这是反应代码块:
<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>
我希望当我更改给定玩家的一个统计数据的输入值时,它只会更改该特定玩家的统计值。但是,它会因每个玩家而改变。
我已经搞砸了一段时间了,努力想知道我做错了什么。我认为这可能与输入在 .map 函数中的呈现方式有关,但我尝试分离测试输入,结果是相同的。任何帮助表示赞赏!
【问题讨论】:
-
你能说明这些结构是在哪里创建的吗?一定有一些别名发生了。
-
@ggorlen 我添加了初始化 matchStats 对象的代码块。希望对您有所帮助!
-
帮助很大,谢谢。
new Array(matchInfo.playersAllowedInGame).fill({可能是问题所在。.fill只为整个 shebang 做一个对象。将其更改为fill().map(e => {stats: statsWithKeys})...之类的内容,并让我知道它是否有效。您可能只想将原语传递给.fill()。 -
不幸的是,这似乎不起作用。我将其更改为以下内容:` const player = new Array(matchInfo.playersAllowedInGame).fill().map(p => { return { stats: statsWithKeys, dropdownOpen: false, id: Math.random().toString(36 ) } }) `
-
应该是
fill().map(e => ({stats: statsWithKeys}));(注意额外的括号)。那么你的改变奏效了吗?问题是statsWithKeys仍然只是一个对象,所以这是个问题。您还必须在map中初始化该对象。基本上,任何时候只要创建一个对象,它就会有别名,因此需要解决多个别名问题。
标签: javascript arrays reactjs object