web-dev-qa-db-fra.com

Profondeur de mise à jour maximale dépassée. Cela peut se produire lorsqu'un composant appelle à plusieurs reprises setState à l'intérieur de componentWillUpdate ou componentDidUpdate

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>
    )
}

}

5
UWGOOSE

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>
6
Sean