Я хочу иметь простой массив, который при нажатии кнопки перемешивает массив, а затем мгновенно отображает новый массив на странице.
Массив перемешивается, когда страница загружается и функция shuffle () успешно вызывается до завершения, когда я нажимаю кнопку Shuffle, но изменение никогда не отображается для пользователя. Я пробовал явно установить состояние и использовать this.setState (), и ни один из них не вызывает рендеринга изменения массива.
const Card = props => {
return (
<p>
{props.title}: {props.text}
</p>
);
};
class Deck extends React.Component {
constructor(props) {
super(props);
this.shuffle = this.shuffle.bind(this);
this.state = {
title: props.title,
count: props.cards.length,
cardsInDeck: props.cards
};
this.shuffle();
}
shuffle(e) {
console.info("shuffling " + this.state.title + "...");
let c = this.state.cardsInDeck.length;
let shuffledArray = this.state.cardsInDeck;
while (c > 0) {
let index = Math.floor(Math.random() * c);
c--;
let temp = this.state.cardsInDeck[c];
shuffledArray[c] = shuffledArray[index];
shuffledArray[index] = temp;
}
//this.state.cardsInDeck = shuffledArray;
this.setState({cardsInDeck: shuffledArray});
console.info("done shuffling " + this.state.title + "...");
};
render() {
return (
<div>
<div className = "card">
<div className = "card-body">
<h5 className = "card-title">{this.state.title} - {this.state.count} cards</h5>
<button type = "button" className = "btn btn-info" onClick = {this.shuffle}>
Shuffle
</button>
</div>
</div>
{this.state.cardsInDeck}
</div>
);
}
}
var jobs = [
{ title: "job1", text: "30", return: "20" },
{ title: "job2", text: "40", return: "30" },
{ title: "job3", text: "50", return: "40" },
{ title: "job4", text: "50", return: "40" },
{ title: "job5", text: "50", return: "40" },
{ title: "job6", text: "50", return: "40" },
{ title: "job7", text: "60", return: "50" }
];
const jobItems = jobs.map(job => (
<Card key = {job.title} title = {job.title} text = {job.text + " " + job.return} />
));
var workers = [
{ name: "worker1", cost: "30" },
{ name: "worker2", cost: "30" },
{ name: "worker3", cost: "30" },
{ name: "worker4", cost: "30" },
{ name: "worker5", cost: "30" },
{ name: "worker6", cost: "30" },
{ name: "worker7", cost: "30" }
];
const workerItems = workers.map(worker => (
<Card key = {worker.name} title = {worker.name} text = {worker.cost} />
));
class App extends React.Component {
render() {
return (
<div className = "row">
<div className = "col">
<Deck title = "Jobs" cards = {jobItems} />
</div>
<div className = "col">
<Deck title = "Workers" cards = {workerItems} />
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
Как я могу показать это изменение пользователю?



Вы изменяете состояние непосредственно в этих строках:
let shuffledArray = this.state.cardsInDeck;
shuffledArray[c] = shuffledArray[index];
shuffledArray[index] = temp;
Может быть источником проблемы ...
Прочтите эту статью ... в ней упоминается ваша проблема и дается несколько хороших решений для нее ... medium.freecodecamp.org/…
+1 А, значит, было все-таки присваивается по ссылке, поэтому любые изменения в [shuffledArray] также изменяли состояние, которое должно считаться неизменным. Это определенно источник моей проблемы. Спасибо!
Проблема не в рендеринге ваших компонентов, а в самом методе shuffle(). Проблема, кажется, здесь:
let shuffledArray = this.state.cardsInDeck;
Это создает переменную, которая содержит Справка для переменной состояния, а не локальную копию, над которой вы можете работать. Правильный способ сделать это:
let shuffledArray = this.state.cardsInDeck.slice();
Затем также измените эту строку:
let temp = this.state.cardsInDeck[c];
к:
let temp = shuffledArray[c];
и он должен работать.
Рабочая вилка: https://codepen.io/anon/pen/xJdNQO?editors=0011
Это сработало. Использование slice () для создания копии, а не ссылки - очень творческий подход. Спасибо!
Рад, что помог. Если вам нравится ES6, вы также можете скопировать с помощью [...this.state.cardsInDeck], если предпочитаете этот синтаксис.
Когда я назначил
shuffledArrayкакthis.state.cardsInDeck, назначается ли он по ссылке? Значит, любые изменения, которые я вношу вshuffledArray, будут внесены вthis.state.cardsInDeck? Я думал, что javascript всегда назначается объектом?