I'm new at React and trying to create a scoreboard app which has the following state:
state = {
home_team: [
{
id: 1,
name: "Jobe Watson",
goals: 0,
behinds: 0,
},
{
id: 2,
name: "James Hird",
goals: 0,
behinds: 0,
},
{
id: 3,
name: "Steven Alessio",
goals: 0,
behinds: 0,
},
{
id: 4,
name: "Che Cockatoo-Collins",
goals: 0,
behinds: 0,
}
],
away_team: [
{
id: 1,
name: "Chris Judd",
goals: 0,
behinds: 0,
},
{
id: 2,
name: "Anthony Koudafidis",
goals: 0,
behinds: 0,
},
{
id: 3,
name: "Steven Silvagni",
goals: 0,
behinds: 0,
},
{
id: 4,
name: "Brendan Fevola",
goals: 0,
behinds: 0,
},
]
}
I am trying to run a score change function as below:
addScore = (i, delta, team, score) => {
const val = eval(`this.state.${team}[${i}].${score} += ${delta}`)
console.log(val)
this.setState( {
[score]: val
})
}
where it is called in the Counter component as follows:
onClick={()=>addScore(index, +1, team, 'goals')
In this case, "index" refers to the player index in either team array, and "team" refers to either "home_team" or "away_team".
The only way I seem to be able to dynamically add the information into the setState method seems to be through a template literal into eval() then calling it in setState.
Knowing there are problems with eval() - are there any other ways to do this? I have tried using new Function()() without success.
Can anyone offer another solution? Thanks in advance.
I think you are bit confused on how to get access value via all available variables, here you go simple way :
// this.state.${team}[${i}].${score}
this.state[team][i][score]
Second you are mutating state, that you shouldn't, you can update state this like :
addScore = (i, delta, team, score) => {
const updated = this.state[team].map((el,index) => {
if(i=== index) {
const score = el.score + delta;
el = { ...el , score }
}
return el
})
this.setState((state) => {
...state ,
[team] : updated
})
}