react - settimeout javascript loop
setInterval en una aplicaciĆ³n React (4)
Gracias @dotnetom, @ greg-herbowicz
Si devuelve "this.state is undefined" - función de temporizador de enlace:
constructor(props){
super(props);
this.state = {currentCount: 10}
this.timer = this.timer.bind(this)
}
Todavía soy bastante nuevo en React, pero he estado avanzando lentamente y he encontrado algo en lo que estoy atascado.
Estoy tratando de construir un componente "temporizador" en React, y para ser honesto, no sé si lo estoy haciendo bien (o de manera eficiente).
En mi código a continuación, configuro el estado para que devuelva un objeto
{ currentCount: 10 }
y he estado jugando con
componentDidMount
,
componentWillUnmount
y
render
y solo puedo hacer que el estado "cuente" de 10 a 9.
Pregunta de dos partes: ¿Qué me estoy equivocando?
Y, ¿hay una manera más eficiente de usar setTimeout (en lugar de usar
componentDidMount
&
componentWillUnmount
)?
Gracias de antemano.
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;
Se actualizó la cuenta regresiva de 10 segundos con Hooks (una nueva propuesta de características que le permite usar el estado y otras características de React sin escribir una clase. Actualmente están en 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''));
Se actualizó la cuenta regresiva de 10 segundos usando el
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;
Veo 4 problemas con su código:
- En su método de temporizador, siempre establece su conteo actual en 10
- Intenta actualizar el estado en el método de representación
-
No utiliza el método
setState
para cambiar realmente el estado - No está almacenando su Id. De intervalo en el estado
Tratemos de arreglar eso:
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>
);
}
Esto daría como resultado un temporizador que disminuye de 10 a -N. Si desea que el temporizador disminuya a 0, puede usar una versión ligeramente modificada:
timer: function() {
var newCount = this.state.currentCount - 1;
if(newCount >= 0) {
this.setState({ currentCount: newCount });
} else {
clearInterval(this.state.intervalId);
}
},