Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/436.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 所有处于React状态的对象都将被修改,而单个对象将发生更改_Javascript_Reactjs - Fatal编程技术网

Javascript 所有处于React状态的对象都将被修改,而单个对象将发生更改

Javascript 所有处于React状态的对象都将被修改,而单个对象将发生更改,javascript,reactjs,Javascript,Reactjs,我正在制作一个表单,用于(稍后)保存一个游戏,其中多个团队可以参与,这样的游戏由多个回合组成 因此,我的React状态包含一个TeamInGame对象数组: export default class TeamInGame{ constructor(nbRounds=2,name=''){ this.nbRounds = nbRounds; this.name = name; this.scores = []; } 在我的表格

我正在制作一个表单,用于(稍后)保存一个
游戏
,其中多个
团队
可以参与,这样的
游戏
由多个
回合组成

因此,我的
React
状态包含一个
TeamInGame
对象数组:

export default class TeamInGame{

    constructor(nbRounds=2,name=''){

        this.nbRounds = nbRounds;
        this.name = name;
        this.scores = [];

    }
在我的表格中,对于每个
团队
我可以拥有与当前
游戏中
回合数
一样多的
分数
。 因此,为了能够在字段更改时跟踪我在状态中应该更新的内容(我的应用程序中只有
select
字段),我将
teamId
roundId
作为道具ID传递

但是,只要
select
值更改,所有相同的
select
字段也会看到其值更改,就好像这些值是共享的一样

例如,在下面的代码中,如果您更改
SelectEachTeam
的团队,则所有
SelectEachTeam
将设置为相同的值(相同的值适用于
SelectScore

我想知道我在
handleAmChange
handleCoreChange
中是否做错了什么

代码如下:

FormAddGame.js

import React, { Component } from 'react';
import SelectEachTeam from './SelectEachTeam'
import { groups } from '../data.json'
import 'bulma/css/bulma.css'
import  TeamInGame  from '../misc/TeamInGame'

class FormAddGame extends Component {

    constructor(props) {
        super(props)
        this.state = {
            nbRounds: 1,
            nbTeams: 3,
            group: groups[0].name,
            teamsInGroup: this.getTeams(groups[0].name),
            teamsInGame: new Array(3).fill(new TeamInGame(1)),

        }
    }

    // retrieve teams based on 'grp'
    getTeams = (grp) => {
        const groupId = groups.findIndex((el) => (el.name === grp))
        return groups[groupId].teams
    }

    // whenever group changes -> retrieve teams belonging to this 
    // group
    handleGroupChange = e => {
        let group = e.target.value
        const teams = this.getTeams(group)
        // update 'group' and 'teams'
        this.setState({ group, teamsInGroup: teams })

    }

    // whenever a team changes
    handleTeamChange = (e, teamId) => {
        console.log(`handleTeamChange: ${teamId}: ${e.target.value}`)
        let teamsInGame = {...this.state.teamsInGame}
        teamsInGame[teamId].name = e.target.value
        console.log(teamsInGame)
        this.setState({ teamsInGame })
    }

    // whenever a score change
    handleScoreChange = (score, teamId, roundId) => {
        console.log(`handleScoreChange: teamId: ${teamId} / roundId: ${roundId} set to ${score}`)
        let teamsInGame = {...this.state.teamsInGame}
        teamsInGame[teamId].scores[roundId] = score
        this.setState({ teamsInGame: teamsInGame })
    }


    handleSubmit = e => {
        e.preventDefault()
        console.log('in handleSubmit()')

    }



    addTeam = () => {
        let nbTeams = this.state.nbTeams
        nbTeams +=1
        this.setState({nbTeams})
    }

    addRound = () => {
        let nbRounds = this.state.nbRounds
        nbRounds += 1
        this.setState( { nbRounds })
    }

    removeTeam = () => {
        let nbTeams = this.state.nbTeams
        nbTeams -=1
        this.setState({nbTeams})

    }


    render() {

        // group selection
        const selectGroup = Object.keys(groups).map(k => {

            return (<option key={k} value={groups[k].name}> {groups[k].name} </option>)
        }
        )

        // 'nbTeams' SelectEachTeam field (1 team select + 'nbRounds' SelectScore)
        const selectEachTeams = Array.from(Array(this.state.nbTeams).keys())
            .map(k => <SelectEachTeam 
                    handleScoreChange={this.handleScoreChange}
                    handleTeamChange={this.handleTeamChange}
                    deleteBox={this.removeTeam}
                    key={k} 
                    numTeam={k+1} 
                    teams={this.state.teamsInGroup} 
                    nbRounds={this.state.nbRounds}
                    teamsInGame={{...this.state.teamsInGame}}
                    teamId={k} />)



        return (
            <section className="section">
                <div className="container">
                    <form onSubmit={this.handleSubmit}>
                        <div className="box">
                            <div className="field">
                                <label className='label'>Poule</label>
                                <div className="control">
                                    <div className="select is-danger">
                                        <select onChange={this.handleGroupChange} value={this.state.group}>
                                            { selectGroup }
                                        </select>
                                    </div>
                                </div>
                            </div>
                        </div>

                        {selectEachTeams}

                        <div className="field is-grouped">
                            <p className="control">
                                <button type="submit" className="button is-danger is-rounded">Enregistrer</button>
                            </p>
                            <p className="control">
                            <i className="fas fa-plus-circle"/>
                                <button type="button" onClick={this.addTeam} className="button is-info is-rounded">Ajouter une équipe </button>
                            </p>
                            <p className="control">
                                <button type="button" onClick={this.addRound} className="button is-info is-rounded">Ajouter une manche </button>
                            </p>

                        </div>
                    </form>
                </div>

            </section>
        );
    }
}

export default FormAddGame;
 import React from 'react';
    import SelectScore from './SelectScore'


    const SelectEachTeam = ({ deleteBox, numTeam, teams, nbRounds, handleTeamChange, handleScoreChange, teamsInGame, teamId }) => {

        const selectTeams = Object.keys(teams).map((k, v) => {

            return (<option key={k} value={teams[k].name}> {teams[k].name} </option>)

        }

        )

        const selectScores = Array.from(Array(nbRounds).keys())
            .map(k => <SelectScore 
                key={k} scoreMax={50} 
                handleScoreChange={handleScoreChange} 
                teamId={teamId} 
                roundId={k} 
                value={teamsInGame[teamId].scores[k]}   />)

        return (
            <div className="box">
                <div className="container">
                    <div className="field">
                        <label className="label">{`Equipe ${numTeam}`}</label>
                        <div className="control">
                            <div className="select is-success">
                                <select onChange={(e) => handleTeamChange(e, teamId)} value={teamsInGame[teamId].name}>
                                    {selectTeams}
                                </select>
                            </div>
                        </div> 
                        </div>           
                        <nav className="level">
                            <div className="level-left">
                                {selectScores}
                            </div>
                            <div className="level-right">
                                <button type="button"  onClick={deleteBox} className="delete"/>
                            </div>
                        </nav>

                        </div>
                </div>

        )


    }

    export default SelectEachTeam;



**SelectScore.js**

import React from 'react';
import 'bulma/css/bulma.css'

const SelectScore = ({ scoreMax, handleScoreChange, value, teamId, roundId }) => {

    console.log(`${teamId}/${roundId}`)

    scoreMax += 1

    const arr = Array.from(Array(51).keys())
        .map(k => (
            <option key={k} value={k}> {k} </option>
        ))



    return (
        <div className="level-item">
            <div className="field">
                <div className="control">
                    <div className="select">
                        <select  onChange={ (e) => handleScoreChange(e.target.value, teamId, roundId) }  value={ value }>
                            {arr}
                        </select>
                    </div>
                </div>

            </div>
        </div>
    );
}

export default SelectScore;

问题来自这样一个事实:在我的状态下,我使用
数组(3).fill(新的TeamInGame(1)
)初始化
TeamInGame
,从而在每个索引处传递单个
TeamInGame
对象的副本


Array(3).fill().map(k=>new TeamInGame(…)
替换这一行可以解决这个问题。

这个问题是因为我在我的状态下用
Array(3.fill().map)初始化了
TeamInGame
,fill(new TeamInGame(1)
,在每个索引处传递了一个
TeamInGame
对象的副本


用数组(3.fill().map(k=>newteamingame(…)
替换这一行可以解决这个问题。

你能告诉我到底发生了什么吗?你能告诉我到底发生了什么吗?
{
    "groups": [
    {
      "name": "Poule A",
      "teams": [{
        "name": "A1"
      },
      {
        "name": "A2"
      },
      {
        "name": "A3"
      },
      {
        "name": "A4"
      },
      {
        "name": "A5"
      }
    ]
    },

    {
      "name": "Poule B",
      "teams": [{
        "name": "B1"
      },
      {
        "name": "B2"
      },
      {
        "name": "B3"
      },
      {
        "name": "B4 "
      },
      {
        "name": "B5"
      },
      {
        "name": "B6"
      }
    ]
    },

    {
      "name": "Poule C",
      "teams": [{
        "name": "C1"
      },
      {
        "name": "C2"
      },
      {
        "name": "C3"
      },
      {
        "name": "C4 "
      }

    ]
    }
  ]
}