Состояние настройки со словарем, не работающим в REACT

В настоящее время я изучаю REACT, и у меня все еще есть проблемы с состоянием. Кажется, я не могу установить состояние со словарем.

class Game extends React.Component {
  state = {
    selectedCharacters: [{"name":"Loup Garou","imgName":"base_loup.png","uniqueKey":"loup","playerName":""},{"uniqueKey":"voyante","imgName":"base_voyante.png","name":"Voyante","maxInGame":1,"left":1}],
    turnList: [],
    gameStatus: "characterSelection",
  };
  saveStateToStorage() {
    localStorage.setItem("gameState", JSON.stringify(this.state));
  }
  startGame = () => {
    //Démarre la partie
    var turns = this.createTurnListFromSelectedCharacters();
    console.log(turns);
    this.setState({
        turnList: turns,
        gameStatus: "gameStarted",
      },
      () => {
        //Sauvegarde l'état du jeu dans le local storage
        this.saveStateToStorage();
        console.log(this.state.turnList);
      }
    );
  };
  createTurnListFromSelectedCharacters = () => {
    //Création de la liste des tours  ainsi que du compteur de joueur en vie
    var turns = [];  
    for (var i = 0; i < this.state.selectedCharacters.length; i++)
    {
      var char = this.state.selectedCharacters[i];
      var turn = turns[char.uniqueKey];
      if (turn === undefined) {
        var namesList = [{ name: char.playerName, isAlive: true }];
        var newTurn = {
          charKey: char.uniqueKey,
          alive: 1,
          inGame: 1,
          names: namesList,
          imgName: char.imgName
        };
        turns[char.uniqueKey] = newTurn;
      }
      else {
        turn.names.push({ name: char.playerName, isAlive: true });
        turn.alive = turn.alive + 1;
        turn.inGame = turn.inGame + 1;
        turns[char.uniqueKey] = turn;
      }
    }
    return turns;
  };  
  render() {...}
}

Первый console.log отображает словарь, правильно сгенерированный моей функцией createTurnListFromSelectedCharacters, а второй console.log в обратном вызове setState ничего не отображает. Если я помещу что-то вроде «turnList: [1,2,3,4,5]» или любой другой массив в setState, он будет работать.


person AnthonyDa    schedule 09.08.2018    source источник
comment
Вы используете [] для настройки словаря. Это нормально? Кроме того, я не могу получить никакого результата от console.log().   -  person devserkan    schedule 10.08.2018
comment
Я пробовал с {}, состояние правильно обновляется, но я не могу сопоставить его.   -  person AnthonyDa    schedule 10.08.2018


Ответы (3)


Вы используете массив [] вместо объекта для своего словаря. Вместо этого используйте обычный объект.

class Game extends React.Component {
  state = {
    selectedCharacters: [{ "name": "Loup Garou", "imgName": "base_loup.png", "uniqueKey": "loup", "playerName": "" }, { "uniqueKey": "voyante", "imgName": "base_voyante.png", "name": "Voyante", "maxInGame": 1, "left": 1 }],
    turnList: {},
    gameStatus: "characterSelection",
  };

  componentDidMount() {
    this.startGame();
  }
  saveStateToStorage() {
    localStorage.setItem("gameState", JSON.stringify(this.state));
  }
  startGame = () => {
    //Démarre la partie
    var turns = this.createTurnListFromSelectedCharacters();
    console.log("foo", turns);
    this.setState({
      turnList: turns,
      gameStatus: "gameStarted",
    },
      () => {
        //Sauvegarde l'état du jeu dans le local storage
        this.saveStateToStorage();
        console.log(this.state.turnList);
      }
    );
  };
  createTurnListFromSelectedCharacters = () => {
    //Création de la liste des tours  ainsi que du compteur de joueur en vie
    var turns = {};
    for (var i = 0; i < this.state.selectedCharacters.length; i++) {
      var char = this.state.selectedCharacters[i];
      console.log( char.uniqueKey );
      var turn = turns[char.uniqueKey];
      if (turn === undefined) {
        var namesList = [{ name: char.playerName, isAlive: true }];
        var newTurn = {
          charKey: char.uniqueKey,
          alive: 1,
          inGame: 1,
          names: namesList,
          imgName: char.imgName
        };
        turns[char.uniqueKey] = newTurn;
      }
      else {
        turn.names.push({ name: char.playerName, isAlive: true });
        turn.alive = turn.alive + 1;
        turn.inGame = turn.inGame + 1;
        turns[char.uniqueKey] = turn;
      }
    }
    return turns;
  };
  render() {
    const { turnList } = this.state;
    return (
        <div>{
        Object.keys(turnList).map( key => (
            <div key={turnList[ key ].charKey}>
            <p>Charkey: {turnList[ key ].charKey}</p>
            <p>Alive: {turnList[ key ].alive}</p>
        </div>
    ))
  }</div>
);
  }
}

ReactDOM.render(<Game />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

person devserkan    schedule 09.08.2018
comment
Хорошая идея, но с этим я не могу использовать функцию карты. У меня есть другой компонент, который проходит через него. - person AnthonyDa; 10.08.2018
comment
@AnthonyDa, я собирался дать то же предложение, что и Object.keys(), а затем сопоставить его. Кажется, вы нашли такое же решение. Тем не менее, я обновил свой ответ. Это простой пример, показывающий, как это можно сделать. - person devserkan; 10.08.2018

Вам нужно установить свое состояние внутри метода конструктора, например:

class Game extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      selectedCharacters: [{ "name": "Loup Garou", "imgName": "base_loup.png", "uniqueKey": "loup", "playerName": "" }, { "uniqueKey": "voyante", "imgName": "base_voyante.png", "name": "Voyante", "maxInGame": 1, "left": 1 }],
      turnList: [],
      gameStatus: "characterSelection",
    };
  }
  ...
}
person Kevin Hernández    schedule 09.08.2018
comment
Здесь нет необходимости использовать конструктор. ОП использует class-fields предложение. - person devserkan; 10.08.2018
comment
Верно, братан, ты получил ответ. - person Kevin Hernández; 10.08.2018

Если я объединим ответ разработчика с чем-то, что я нашел в другой теме. Я получаю это:

class Game extends React.Component {
  state = {
    selectedCharacters: [{ "name": "Loup Garou", "imgName": "base_loup.png", "uniqueKey": "loup", "playerName": "" }, { "uniqueKey": "voyante", "imgName": "base_voyante.png", "name": "Voyante", "maxInGame": 1, "left": 1 }],
    turnList: {},
    gameStatus: "characterSelection",
  };
  startGame = () => {
    //Démarre la partie
    var turns = this.createTurnListFromSelectedCharacters();
    console.log("foo", turns);
    this.setState({
      turnList: turns,
      gameStatus: "gameStarted",
    },
      () => {
        //Sauvegarde l'état du jeu dans le local storage
        this.saveStateToStorage();
        console.log(this.state.turnList);
      }
    );
  };
  createTurnListFromSelectedCharacters = () => {
    //Création de la liste des tours  ainsi que du compteur de joueur en vie
    var turns = {};
    for (var i = 0; i < this.state.selectedCharacters.length; i++) {
      var char = this.state.selectedCharacters[i];
      console.log( char.uniqueKey );
      var turn = turns[char.uniqueKey];
      if (turn === undefined) {
        var namesList = [{ name: char.playerName, isAlive: true }];
        var newTurn = {
          charKey: char.uniqueKey,
          alive: 1,
          inGame: 1,
          names: namesList,
          imgName: char.imgName
        };
        turns[char.uniqueKey] = newTurn;
      }
      else {
        turn.names.push({ name: char.playerName, isAlive: true });
        turn.alive = turn.alive + 1;
        turn.inGame = turn.inGame + 1;
        turns[char.uniqueKey] = turn;
      }
    }
    return turns;
  };
  render() {
    return (
      <div>
        {Object.keys(props.aliveCount).map((turn, i) => {
          return (
            <div>
              <img alt={props.aliveCount[turn].imgName} src= {require("../../public/images/" + props.aliveCount[turn].imgName)} />
              {props.aliveCount[turn].alive}/{props.aliveCount[turn].inGame}
            </div>
          );
        })}
      </div>
    );
  }
}

Мне нужно было установить свой объект, используя {}, а затем пользователь Object.keys, чтобы сопоставить его.

person AnthonyDa    schedule 10.08.2018