gpt4 book ai didi

javascript - 在 React componentDidMount() 中使用条件计时器间隔不起作用

转载 作者:行者123 更新时间:2023-11-28 00:09:14 25 4
gpt4 key购买 nike

更新

我在下面 self 回答,但是可能可以提供一个更优雅的解决方案,更多“在 React 中思考”。

<小时/>

我正在从 CodyHouse 创建这个“动画标题”jQuery 小部件的 React 版本:http://codyhouse.co/demo/animated-headlines/index.html (点击“类型”)

到目前为止,一切都很好。我已经让组件正常工作,以便状态更改可以很好地管理 className 分配,并且标题(我的代码中的“短语”)一次以一个字母动画,并按顺序循环显示每个短语,然后重置。

但是,我想做的是在前进字母时有一个 300 毫秒的计时器间隔,并在出现新短语时有 2000 毫秒的暂停。 p>

目前,尽管我尝试在循环进入新短语时设置更长的animationDelay状态(请参见下面代码中的[0a]),但componentDidMount()中的计时器间隔永远不会改变。为什么是这样?如何让 componentDidMount() 使用当前更改后的 state.animationDelay?

注意:您可以忽略下面的大部分代码。只有注释行和 componentDidMount() 是有问题的。为了完整起见,我粘贴了其余部分。

var React = require('react'),
ClassNames = require('classnames');

var AnimatedPhrases = React.createClass({

getInitialProps: function () {

return {
animateType: 'type'
}
},

getInitialState: function () {

return {
animationDelay:300,
visible: 0,
currentLetter: 0,
currentPhrase: 0,
phraseCount: this.props.phrases.length
}
},

componentDidMount: function(){
this.timer = setInterval(this.tick, this.state.animationDelay);
},

componentWillUnmount: function(){

clearInterval(this.timer);
},

isLastLetter: function () {

var phrases = this.props.phrases;
var currentPhraseLength = phrases[this.state.currentPhrase].name.length;

return (this.state.currentLetter === currentPhraseLength-1);
},

isLastPhrase: function () {

var phrases = this.props.phrases;
var currentPhraseLength = phrases[this.state.currentPhrase].name.length;

return (this.state.currentPhrase === this.state.phraseCount-1
&& this.state.currentLetter === currentPhraseLength-1);
},

tick: function(){

var phrases = this.props.phrases;
var currentPhraseLength = phrases[this.state.currentPhrase].name.length;

// if we are on the last letter of the current phrase, we need
// to increment the current phrase at the next pass [0] and
// pause for longer [0a]
// unless it's the last phrase
// in which case we reset the current phrase and letter. [1]
// If we are in the middle of a word, continue to increment
// only the current letter [2]
if (this.isLastPhrase()) {
this.setState({
currentPhrase: 0, // [1]
currentLetter: 0, // [1]
});
}
if (this.isLastLetter()) {
this.setState({
currentLetter: 0, // [0]
currentPhrase: this.state.currentPhrase+1, // [0]
animationDelay: 2000 // [0a]
});
} else {
this.setState({
currentLetter: this.state.currentLetter+1 // [2]
});
}
},

buildPhrase: function (phrase, index) {

var isVisible = this.state.currentPhrase == index ? true : false;

var classes = ClassNames({
'is-visible': isVisible,
'is-hidden': !isVisible
});

var text = '';

if ( phrase.hasOwnProperty('name') ) {

text = phrase.name;

if (isVisible) {
// cycle through letters and create an <i> per letter
// with class depending on matching the current letter
var splitPhrase = this.singleLetters(text);

if (phrase.hasOwnProperty('url') && phrase.hasOwnProperty('id')) {
return <a className={ classes } key={index} href={phrase.url}>{ splitPhrase }</a>
} else {
return <b className={ classes } key={index}>{ splitPhrase }</b>
}
}
}
},

singleLetters: function (phrase, isVisible) {

var currentLetter = this.state.currentLetter;
var letters = phrase.split("");
var letterCount = phrase.length;

var newLetters = letters.map(function (letter, index) {
return <i className={ currentLetter >= index ? 'in' : 'out' } key={index}>{letter}</i>
});

return newLetters;
},

render: function() {

var buildPhrase = this.buildPhrase;

phrases = this.props.phrases.map(function (phrase, index) {
return buildPhrase(phrase, index);
});

var classes = ClassNames('animated-phrase', this.props.animateType);

return (
<h1 className="animated-phrase letters type">
<span>{this.props.headline}</span>
<span className="word-wrapper waiting">
{ phrases }
</span>
</h1>
)
}
});

module.exports = AnimatedPhrases;

最佳答案

好吧,最后,实际上这只是我在tick()中设置状态后清除计时器的情况,就像这样。如果有人知道更优雅的解决方案(最有可能!)请发布:)

tick: function(){

var phrases = this.props.phrases;
var currentPhraseLength = phrases[this.state.currentPhrase].name.length;

// if we are on the last letter of the current phrase, we need
// to increment the current phrase at the next pass [0]
// unless it's the last phrase
// in which case we reset the current phrase and letter [1]
// if we are in the middle of a word, continue to increment
// only the current letter [2]
if (this.isLastPhrase()) {
this.setState({
currentPhrase: 0, // [1]
currentLetter: 0, // [1]
});
}
if (this.isLastLetter()) {
this.setState({
currentLetter: 0, // [0]
currentPhrase: this.state.currentPhrase+1, // [0]
animationDelay: 2000
});

// this fixes it!
clearInterval(this.timer);
this.componentDidMount();

} else {
this.setState({
currentLetter: this.state.currentLetter+1, // [2],
animationDelay: 300
});

clearInterval(this.timer);
this.componentDidMount();
}
},

关于javascript - 在 React componentDidMount() 中使用条件计时器间隔不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31059968/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com