Je veux regrouper les éléments les uns après les autres. Mais il n'affiche que le dernier élément du tableau.
La sortie attendue affiche "a" après 2 secondes "b" et ainsi de suite.
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id='root'></div>
class Main extends React.Component {
constructor(props) {
super(props)
this.state = {
role: ["a","b","c"],
display: "",
}
}
componentDidMount() {
for (let i of this.state.role) {
setTimeout(() => {
this.setState({ display: i})
}, 2000)
}
}
render() {
return (
<div>
<h3>{this.state.display}</h3>
</div>
)
}
}
ReactDOM.render(<Main />, document.getElementById('root'))
3 Réponses :
Le problème est que vous utilisez une boucle pour créer un timeout sur componentDidMount. Dans un tel cas, ce qui se passerait, c'est que la boucle se terminera immédiatement en créant 3 minuteries qui se résolvent à peu près au même intervalle de 2 secondes à partir du début et de setState, puis regroupent les trois appels de mise à jour d'état, ce qui entraîne uniquement le dernier à afficher.
Pour résoudre ce problème, vous pouvez utiliser setInterval comme ci-dessous
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"/>
class Main extends React.Component {
constructor(props) {
super(props)
this.state = {
role: ["a","b","c"],
display: "",
}
}
componentDidMount() {
var index = 0;
this.timer = setInterval(() => {
this.setState({ display: this.state.role[index]});
index = (index + 1)%(this.state.role.length);
}, 2000)
}
componentWillUnmounnt() {
clearInterval(this.timer);
}
render() {
return (
<React.Fragment>
<h3>{this.state.display}</h3>
</React.Fragment>
)
}
}
ReactDOM.render(<Main />, document.getElementById('root'));
Si vous ne voulez pas répéter l'ordre des rôles encore et encore à l'écran, vous pouvez effacer l'intervalle une fois que la taille du tableau est atteinte
Si vous voulez une minuterie pour 1 cycle, vous pouvez utiliser setTimeout à la place
Vous pouvez utiliser plusieurs fois l ' index pour créer 3 délais différents.
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id='root'></div>
class Main extends React.Component {
constructor(props) {
super(props)
this.state = {
role: ["a","b","c"],
display: "",
}
}
componentDidMount() {
this.state.role.forEach((item, index) => {
setTimeout(() => {
this.setState({ display: item})
}, 2000*(index+1))
})
}
render() {
return (
<div>
<h3>{this.state.display}</h3>
</div>
)
}
}
ReactDOM.render(<Main />, document.getElementById('root'))
Le problème est que for (x of y) s'exécute directement et que les trois setTimeouts sont créés presque en même temps, alors vous ne voyez que le résultat du dernier car ils ont 1-2 ms de différence entre eux.
J'ai utilisé for (x in y) à la place pour avoir l'index de l'élément. Ensuite, j'utilise l'index de l'élément pour calculer son délai d'expiration en fonction de son index.
Voici mon approche:
import React, { Component } from "react";
export default class Main extends Component {
constructor(props) { super(props);
this.state = {
role: ["a", "b", "c"],
display: ""
};
}
componentDidMount() {
for (let i in this.state.role) {
setTimeout(() => {
this.setState({
display: this.state.role[i],
});
}, 2000 * i);
}
}
render() {
return (
<>
<h3>{this.state.display}</h3>
</>
);
}
}
à quelle erreur ou problème rencontrez-vous? et qu'attendez-vous après 4 secondes si le message
as'affiche à nouveau?Vous avez mal fermé les crochets dans
componentDidMount, en particulier lorsque vous avez appelésetStateetsetTimeout.Même si je vois pourquoi vous voudriez utiliser setState (car cela provoque un nouveau rendu), je pense qu'il n'est pas nécessaire de stocker pour indiquer un tableau en double uniquement à des fins sémantiques.