Je fais réagir le projet de jeu de la vie de Conway et cela fonctionnait très bien, mais lorsque j'ai ajouté les deux derniers boutons pour effacer la carte et que certaines autres fonctionnalités réagissaient, cela m'a donné cette erreur
Maximum update depth exceeded. This can happen when a component
repeatedly calls setState inside componentWillUpdate or
componentDidUpdate. React limits the number of nested updates to
prevent infinite loops.
D'après les extraits de code que cela m'a montré, il semble que la fonction clear () soit le problème ici, mais je ne pense pas avoir défini l'état dans un render () pour déclencher une boucle infinie. Voici tout le code pour le clear et componentDidMount
, je n'ai pas de componentWillUpdate
ou componentDidUpdate
dans mon application.
la fonction clear () et Play dans la classe principale
EDIT 1: Cela me dit qu'il y a quelque chose qui ne va pas avec setState dans la fonction play (), cependant, j'ai toujours implémenté la fonction play de cette façon et cela fonctionnait toujours depuis le début ....
clear = ()=>{
var g = Array(this.rows).fill().map(()=> Array(this.cols).fill(false));
this.setState({
generations:0,
fullGrid: g
})
}
.....
play = () => {
let g1 = this.state.fullGrid;
let g2 = arrayClone(this.state.fullGrid);
for (let i = 0; i < this.rows; i++) {
for (let j = 0; j < this.cols; j++) {
let count = 0;
if (i > 0)
if (g1[i - 1][j]) count++;
if (i > 0 && j > 0)
if (g1[i - 1][j - 1]) count++;
if (i > 0 && j < this.cols - 1)
if (g1[i - 1][j + 1]) count++;
if (j < this.cols - 1)
if (g1[i][j + 1]) count++;
if (j > 0)
if (g1[i][j - 1]) count++;
if (i < this.rows - 1)
if (g1[i + 1][j]) count++;
if (i < this.rows - 1 && j > 0)
if (g1[i + 1][j - 1]) count++;
if (i < this.rows - 1 && this.cols - 1)
if (g1[i + 1][j + 1]) count++;
if (g1[i][j] && (count < 2 || count > 3)) g2[i][j] = false;
if (!g1[i][j] && count === 3) g2[i][j] = true;
}
}
this.setState({
fullGrid: g2,
generations: this.state.generations + 1
});
}
playButton = ()=>{
clearInterval(this.intervalId);
this.intervalId = setInterval(this.play, this.speed);
}
pauseButton = ()=>{
clearInterval(this.intervalId);
}
slow = ()=>{
this.speed = 1000;
this.playButton();
}
fast = ()=>{
this.speed = 100;
this.playButton();
}
clear = ()=>{
var g = Array(this.rows).fill().map(()=> Array(this.cols).fill(false))
this.setState({
generations:0,
fullGrid: g
})
}
La classe Button
class Buttons extends React.Component{
handleSelect = (evt) =>{
this.props.gridSize(evt);
}
render(){
return (
<div className="center">
<ButtonToolbar>
<button className='btn btn-info' onClick={this.props.playButton}>
PLAY
</button>
<button className='btn btn-info' onClick={this.props.pauseButton}>
PAUSE
</button>
<button className='btn btn-info' onClick={this.props.clear}>
CLEAR
</button>
<button className='btn btn-info' onClick={this.props.slow}>
SLOW
</button>
<button className='btn btn-info' onClick={this.props.fast}>
FAST
</button>
<button className='btn btn-info' onClick={this.props.seed}>
SEED
</button>
<DropdownButton
title="Grid Size"
id="size-menu"
onSelect={this.handleSelect}
>
<MenuItem eventKey="1">20x10</MenuItem>
<MenuItem eventKey="2">50x30</MenuItem>
<MenuItem eventKey="3">70x50</MenuItem>
</DropdownButton>
</ButtonToolbar>
</div>
)
}
}
Vos gestionnaires onClick
sont appelés en continu. Modifiez-les en fonctions qui renvoient la fonction que vous souhaitez appeler et cela devrait résoudre votre problème.
Exemple:
<button className='btn btn-info' onClick={() => this.props.playButton}>
PLAY
</button>