В настоящее время я изучаю 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, он работает.
Я пробовал использовать {}, состояние обновляется правильно, но я не могу его отобразить.



Вам нужно установить ваше состояние внутри метода конструктора, например:
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.
Хорошо, братан, ты получил ответ.
Вы используете массив [] вместо объекта для своего словаря. Вместо этого используйте обычный предмет.
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, я собирался дать то же предложение, что и Object.keys(), а затем отобразить его. Кажется, вы нашли такое же решение. Тем не менее, я обновил свой ответ. Это простой пример, показывающий, как это можно сделать.
Если я объединю ответ разработчика с чем-то, что я нашел по другой теме. Я получаю это:
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, чтобы отобразить его.
Вы используете
[]для настройки словаря. Это нормально? Кроме того, я не могу получить никаких результатов отconsole.info().