我在react.js中重启计时器时遇到问题。我想要实现的是:当计时器达到某个值(如我的例子中的f.ex 20)时,它重新启动到0并自动继续,没有任何事件,再次自动计数。
提前谢谢!
这是我的代码:
import React, { Component } from 'react';
require('../../sass/main.scss');
class TypeAnimation extends Component {
constructor(props) {
super(props);
this.state = {
sec: 0,
};
}
componentDidMount() {
this.textInterval = setInterval(() => {
this.setState({
sec: this.state.sec + 1
});
}, 100);
}
componentDidUpdate(prevProps, prevState) {
if (this.state.sec === 20) {
clearInterval(this.textInterval);
this.firstTimeout = setTimeout(() => {
this.setState({
sec: 0
});
}, 3000);
}
}
render() {
const inText = this.props.text[0];
const firstLine = inText.substr(0, this.state.sec);
return (
<div>
<h2>
{firstLine}
<span className='blinker'> | </span>
</h2>
</div>
);
}
}
export default TypeAnimation;
答案 0 :(得分:2)
this.textInterval = setInterval(() => {
this.setState(prevState => ({
sec: prevState.sec < 20 ? prevState.sec + 1 : 0
}));
}, 1000);
答案 1 :(得分:1)
P.S确保清除componentWillUnmount生命周期的间隔。
componentDidMount() {
this.textInterval = setInterval(() => {
this.setState((prevState, currentProps) => {
return {sec: prevState.sec !== 20 ? prevState.sec+1 : 0};
});
}, 1000);
}
答案 2 :(得分:1)
更新计时器中的状态,或者如果您要等待componentDidUpdate
,则每次都要启动一个新的计时器。但无论如何,请确保不将基于当前状态的对象传递到setState
,这是一个错误; details。而是使用回调版本:
this.setState(prevState => ({sec: (prevState.sec + 1) % 20})); // % 20 resets to 0 at 20
我们在此处执行计时器中的所有更新(无componentDidUpdate
):
class TypeAnimation extends React.Component {
constructor(props) {
super(props);
this.state = {
sec: 0,
};
}
componentDidMount() {
this.textInterval = setInterval(() => {
// Note use of the callback version, it matters
this.setState(prevState => ({sec: (prevState.sec + 1) % 20})); // % 20 resets to 0 at 20
}, 100);
}
render() {
const inText = this.props.text[0];
const firstLine = inText.substr(0, this.state.sec);
return (
<div>
<h2>
{firstLine}
<span className='blinker'> | </span>
</h2>
</div>
);
}
}
ReactDOM.render(
<TypeAnimation text={["abcdefghijklmnopqrstuvwxyz"]} />,
document.getElementById("root")
);
&#13;
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
&#13;
在安排下一次更新之前,我们需要componentDidUpdate
(例如,setTimeout
,而不是setInterval
):
class TypeAnimation extends React.Component {
constructor(props) {
super(props);
this.state = {
sec: 0,
};
}
scheduleUpdate() {
if (this.textTimer) {
clearTimeout(this.textTimer);
}
this.textTimer = setTimeout(() => {
// Note use of the callback version, it matters
this.setState(prevState => ({sec: (prevState.sec + 1) % 20})); // % 20 resets to 0 at 20
this.textTimer = 0;
}, 100);
}
componentDidMount() {
this.scheduleUpdate();
}
componentDidUpdate() {
this.scheduleUpdate();
}
render() {
const inText = this.props.text[0];
const firstLine = inText.substr(0, this.state.sec);
return (
<div>
<h2>
{firstLine}
<span className='blinker'> | </span>
</h2>
</div>
);
}
}
ReactDOM.render(
<TypeAnimation text={["abcdefghijklmnopqrstuvwxyz"]} />,
document.getElementById("root")
);
&#13;
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
&#13;