我有一个React应用程序,需要显示一些文本,句子之间的间隔不同,一次显示一个。
所以我要做的是将所有句子放入数组中并创建一个setInterval函数:
startShowingText() {
let i = 0
this.setState({
timer: window.setInterval(() => {
this.setState({
sentence: SENTENCES[i]
})
i += 1
}, this.state.startingDuration)
})
}
不幸的是,这种方法有很多缺点:
1)需要检查才能终止;
2)我无法动态修改时间,所以一旦设置了this.state.startingDuration
,那将是所有句子的速度...
3)由于某些原因,如果我将window.setInterval
函数分配给该状态之外的变量,则不会执行该段代码:
startShowingText() {
let i = 0
console.log('here')
const timer = window.setInterval(() => {
this.setState({
sentence: SENTENCES[i]
})
i += 1
}, this.state.startingDuration)
console.log('there')
}
此代码仅用于打印:
这里
那里
不触发实际计时器。
如何改善代码并动态调整间隔?
您可以使用从游戏开发界借来的一种方法,在借书中,它们创建以特定刻度间隔运行的“游戏循环”。在循环中,您可以根据当前循环迭代确定是否该输出句子了。
一个粗略的例子:
const sentences = {
"My first sentence.": 1,
"My second sentence.": 20,
"My third sentence.": 25,
"My fourth sentence.": 40
};
const ticks = 100;
const maxLoops = 100;
const i = setInterval(writeLoop, ticks);
let loopCounter = 0;
function writeLoop() {
if (loopCounter > maxLoops) {
clearInterval(i);
}
for (sentence in sentences) {
let targetLoop = sentences[sentence];
if (loopCounter == targetLoop) {
document.write('<div>'+sentence+'</div>');
}
}
loopCounter = loopCounter + 1;
}
您可以使用setTimeout
和如下所示的递归函数;
class App extends React.Component {
sentences = ["sentence1", "sentence2", "sentence3"];
delayTime = [1000, 500, 3000];
constructor(props) {
super(props);
this.state = {
selected: 0,
}
}
componentDidMount() {
this.showSentence();
}
showSentence() {
const { selected } = this.state;
setTimeout(() => {
this.setState({ selected: (selected + 1) % 3});
this.showSentence();
}, this.delayTime[selected])
}
render() {
return (
<div>{this.sentences[this.state.selected]}</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<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>
<div id='app'/>
结果:句子1 -1s-> 句子2 -0.5s-> 句子3 -3s-> 句子1再次]]
您可以递归调用setTimeout
并根据当前对话框块更新速度。