Состояние настройки с неработающим словарем в 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.info(turns);
    this.setState({
        turnList: turns,
        gameStatus: "gameStarted",
      },
      () => {
        //Sauvegarde l'état du jeu dans le local storage
        this.saveStateToStorage();
        console.info(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.info отображает словарь, правильно сгенерированный моей функцией createTurnListFromSelectedCharacters, а второй console.info в обратном вызове setState ничего не отображает. Если я помещаю что-то вроде 'turnList: [1,2,3,4,5]' или любой массив в setState, он работает.

Вы используете [] для настройки словаря. Это нормально? Кроме того, я не могу получить никаких результатов от console.info().

devserkan 09.08.2018 23:08

Я пробовал использовать {}, состояние обновляется правильно, но я не могу его отобразить.

AnthonyDa 10.08.2018 10:11
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
1
2
104
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

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",
    };
  }
  ...
}

Здесь нет необходимости использовать конструктор. OP использует предложение class-fields.

devserkan 09.08.2018 23:03

Хорошо, братан, ты получил ответ.

Kevin Hernández 09.08.2018 23:19
Ответ принят как подходящий

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

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.info("foo", turns);
    this.setState({
      turnList: turns,
      gameStatus: "gameStarted",
    },
      () => {
        //Sauvegarde l'état du jeu dans le local storage
        this.saveStateToStorage();
        console.info(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.info( 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>

Идея Goot, но с этим я не могу использовать функцию карты. У меня есть еще один компонент, который проходит через него.

AnthonyDa 10.08.2018 07:59

@AnthonyDa, я собирался дать то же предложение, что и Object.keys(), а затем отобразить его. Кажется, вы нашли такое же решение. Тем не менее, я обновил свой ответ. Это простой пример, показывающий, как это можно сделать.

devserkan 10.08.2018 13:57

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

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.info("foo", turns);
    this.setState({
      turnList: turns,
      gameStatus: "gameStarted",
    },
      () => {
        //Sauvegarde l'état du jeu dans le local storage
        this.saveStateToStorage();
        console.info(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.info( 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, чтобы отобразить его.

Другие вопросы по теме