在没有eval()的情况下使用模板文字将值动态添加到React中的setState

我是React的新手,正在尝试创建一个具有以下状态的记分板应用程序:

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,
      },
    ]
  }

我正在尝试运行分数更改功能,如下所示:

addScore = (i, delta, team, score) => {
    const val = eval(`this.state.${team}[${i}].${score} += ${delta}`)
    console.log(val)
    this.setState( {
        [score]: val
    })
  }

在Counter组件中调用的位置,如下所示:

onClick={()=>addScore(index, +1, team, 'goals')

在这种情况下,“索引”指的是任一团队数组中的玩家索引,而“团队”指的是“ home_team”或“ away_team”。

我似乎能够将信息动态添加到setState方法中的唯一方法似乎是通过将模板文字转换为eval(),然后在setState中进行调用。

知道eval()存在问题-还有其他方法可以做到这一点吗?我尝试使用新的Function()()失败。

谁能提供其他解决方案?提前致谢。

评论
  • 夜ト负紅唇
    夜ト负紅唇 回复

    我认为您对如何通过所有可用变量获取访问值感到困惑,在这里您可以采用以下简单方法:

    // this.state.${team}[${i}].${score}
    
    this.state[team][i][score]
    

    其次,你正在改变状态,你不应该,

    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
        })
    }
    

  • in_ut
    in_ut 回复

    您需要prevState。像这样

    addScore = (i, delta, team, score) => {
        this.setState(prevState => ({
            items: {
                ...prevState.items,
                [prevState.items[i][score]]: delta,
            },
        }));
    };