Ayant ce code en tête:
var Component = React.createClass({
getInitialState: function () {
return {position: 0};
},
componentDidMount: function () {
setTimeout(this.setState({position: 1}), 3000);
},
render: function () {
return (
<div className="component">
{this.state.position}
</div>
);
}
});
ReactDOM.render(
<Component />,
document.getElementById('main')
);
L'état n'est-il pas censé changer seulement après 3 secondes? Cela change immédiatement.
Mon objectif principal ici est de changer l'état toutes les 3 secondes (avec setInterval()
), mais comme cela ne fonctionnait pas, j'ai essayé setTimeout()
, qui ne fonctionne pas non plus. Des lumières sur ça? Merci!
Faire
setTimeout(
function() {
this.setState({position: 1});
}
.bind(this),
3000
);
Sinon, vous passez le résultat de setState
à setTimeout
.
setTimeout(() => {
this.setState({ position: 1 });
}, 3000);
Ce qui précède fonctionnerait également car la fonction de flèche ES6 ne modifie pas le contexte de this
.
Chaque fois que nous créons un délai d’expiration, nous devrions l’effacer sur le composantWillUnmount, s’il ne s’est pas encore déclenché.
let myVar;
const Component = React.createClass({
getInitialState: function () {
return {position: 0};
},
componentDidMount: function () {
myVar = setTimeout(()=> this.setState({position: 1}), 3000)
},
componentWillUnmount: () => {
clearTimeout(myVar);
};
render: function () {
return (
<div className="component">
{this.state.position}
</div>
);
}
});
ReactDOM.render(
<Component />,
document.getElementById('main')
);
setState
est invoqué immédiatement en raison de la parenthèse! Enveloppez-le dans une fonction anonyme, puis appelez-le:
setTimeout(function() {
this.setState({position: 1})
}.bind(this), 3000);
Votre portée de code (this
) sera votre objet window
, pas votre composant react, et c’est pourquoi setTimeout(this.setState({position: 1}), 3000)
plantera de cette façon.
Cela vient de javascript pas react, c'est js fermeture
Ainsi, afin de lier la portée de votre composant de réaction actuel, procédez comme suit:
setTimeout(function(){this.setState({position: 1})}.bind(this), 3000);
Ou, si votre navigateur prend en charge es6 ou si votre projet prend en charge la compilation de es6 à es5, essayez également arrow, car arrow func corrige ce problème:
setTimeout(()=>this.setState({position: 1}), 3000);
Je sais que cela est un peu vieux, mais il est important de noter que React recommande d'effacer l'intervalle lorsque le composant se démonte: https://reactjs.org/docs/state-and-lifecycle.html
J'aime donc ajouter cette réponse à cette discussion:
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
componentWillUnmount() {
clearInterval(this.timerID);
}
Il y a 3 façons d'accéder à la portée à l'intérieur de la fonction 'setTimeout'
Premier,
const self = this
setTimeout(function() {
self.setState({position:1})
}, 3000)
Deuxièmement, il faut utiliser la fonction flèche ES6, la fonction flèche n’ayant pas elle-même de portée (ceci)
setTimeout(()=> {
this.setState({position:1})
}, 3000)
La troisième consiste à lier la portée à l'intérieur de la fonction
setTimeout(function(){
this.setState({position:1})
}.bind(this), 3000)
Voici comment vous appelez timeout sans appeler de fonctions supplémentaires.
setTimeout(this.setState.bind(this, {position:1}), 3000);
Utilise function.prototype.bind ()
setTimeout prend l'emplacement de la fonction et le conserve dans le contexte.
setTimeout(this.setState, 3000, {position:1});
Probablement utilise la même méthode bind à un moment donné
Le setTimeout prend seulement l'emplacement de la fonction et la fonction a déjà le contexte? En tout cas, ça marche!
NOTE: Celles-ci fonctionnent avec toutes les fonctions que vous utilisez en js.
Vous avez commis une erreur de déclaration de syntaxe, utilisez la déclaration setTimeout appropriée
message:() => {
setTimeout(() => {this.setState({opened:false})},3000);
return 'Thanks for your time, have a Nice day ????!
}