Je suis encore assez nouveau chez React, mais j'ai progressé lentement et j'ai rencontré quelque chose sur lequel je suis coincé.
J'essaie de créer un composant "timer" dans React, et pour tout vous dire, je ne sais pas si je le fais correctement (ou efficacement). Dans mon code ci-dessous, j'ai défini l'état pour retourner un objet { currentCount: 10 }
et j'ai joué avec componentDidMount
, componentWillUnmount
et render
et je ne peux obtenir que l'état " compte à rebours "de 10 à 9.
Question en deux parties: Qu'est-ce qui ne va pas? Et existe-t-il un moyen plus efficace d'utiliser setTimeout (plutôt que componentDidMount
& componentWillUnmount
)?
Merci d'avance.
import React from 'react';
var Clock = React.createClass({
getInitialState: function() {
return { currentCount: 10 };
},
componentDidMount: function() {
this.countdown = setInterval(this.timer, 1000);
},
componentWillUnmount: function() {
clearInterval(this.countdown);
},
timer: function() {
this.setState({ currentCount: 10 });
},
render: function() {
var displayCount = this.state.currentCount--;
return (
<section>
{displayCount}
</section>
);
}
});
module.exports = Clock;
Je vois 4 problèmes avec votre code:
setState
pour réellement changer l'étatEssayons de résoudre ce problème:
componentDidMount: function() {
var intervalId = setInterval(this.timer, 1000);
// store intervalId in the state so it can be accessed later:
this.setState({intervalId: intervalId});
},
componentWillUnmount: function() {
// use intervalId from the state to clear the interval
clearInterval(this.state.intervalId);
},
timer: function() {
// setState method is used to update the state
this.setState({ currentCount: this.state.currentCount -1 });
},
render: function() {
// You do not need to decrease the value here
return (
<section>
{this.state.currentCount}
</section>
);
}
Cela entraînerait une minuterie qui passe de 10 à -N. Si vous voulez une minuterie qui diminue à 0, vous pouvez utiliser une version légèrement modifiée:
timer: function() {
var newCount = this.state.currentCount - 1;
if(newCount >= 0) {
this.setState({ currentCount: newCount });
} else {
clearInterval(this.state.intervalId);
}
},
Compte à rebours de 10 secondes mis à jour avec class Clock extends Component
import React, { Component } from 'react';
class Clock extends Component {
constructor(props){
super(props);
this.state = {currentCount: 10}
}
timer() {
this.setState({
currentCount: this.state.currentCount - 1
})
if(this.state.currentCount < 1) {
clearInterval(this.intervalId);
}
}
componentDidMount() {
this.intervalId = setInterval(this.timer.bind(this), 1000);
}
componentWillUnmount(){
clearInterval(this.intervalId);
}
render() {
return(
<div>{this.state.currentCount}</div>
);
}
}
module.exports = Clock;
Compte à rebours de 10 secondes mis à jour à l'aide de crochets (nouvelle proposition de fonctionnalité vous permettant d'utiliser l'état et d'autres fonctionnalités React sans écrire de classe. Elles sont actuellement dans React v16.7.0-alpha).
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
const Clock = () => {
const [currentCount, setCount] = useState(10);
const timer = () => setCount(currentCount - 1);
useEffect(
() => {
if (currentCount <= 0) {
return;
}
const id = setInterval(timer, 1000);
return () => clearInterval(id);
},
[currentCount]
);
return <div>{currentCount}</div>;
};
const App = () => <Clock />;
ReactDOM.render(<App />, document.getElementById('root'));
Merci @dotnetom, @ greg-herbowicz
S'il renvoie "this.state is undefined" - fonction de minuterie de liaison:
constructor(props){
super(props);
this.state = {currentCount: 10}
this.timer = this.timer.bind(this)
}