[英]React.JS: Sequence of timed state changes
我有一個簡單的Web應用程序,其中包含一個父組件和三個子組件。 孩子們只是div框,可以根據其活動的屬性將背景顏色從白色更改為紅色。 animateChild()函數可用於將特定的孩子變成紅色,然后在1秒后再次變成白色。
我的目標是“播放”任意子動畫序列,每個動畫之間的間隔為1s。 這應該在animateSequence()函數中發生。
實現此目的的最初想法是使用for循環,並在每次迭代時在window.setTimeout()中調用animateChild(childNum) 。 但是,這沒有用。 我猜是因為setState()是異步的,並且幾個狀態更改被合並在一起。
什么是完成動畫序列(例如,子1,子2,子3)的最佳方法,每個動畫之間的間隔時間為1s? 非常感謝你
JavaScript代碼:
class Child extends React.Component {
render() {
var childStyle = "basic";
if (this.props.active){
childStyle += " active";
}
return (
<div className={childStyle}></div>
);
}
}
class Parent extends React.Component {
constructor(){
super();
this.state = {
firstChildActive:false,
secondChildActive:false,
thirdChildActive:false,
};
this.animateChild = this.animateChild.bind(this);
}
animateChild(childNum){
var childDict = ["firstChildActive","secondChildActive","thirdChildActive"];
this.setState({[childDict[childNum]]: true}, function() {
window.setTimeout(() => {
this.setState({[childDict[childNum]]: false});
},1000);
});
}
animateSequence(){
// animate child 2, then child 1, then child 3, then child 1, etc.
}
render() {
return (
<div className ="container">
<Child active={this.state.firstChildActive}/>
<Child active={this.state.secondChildActive}/>
<Child active={this.state.thirdChildActive}/>
</div>
);
}
}
ReactDOM.render(<Parent />,document.getElementById('app'));
CSS代碼:
.container{
display:flex;
width:100%;
justify-content: space-between;
}
.basic{
margin: 10px;
width: 100px;
height:100px;
border: 2px solid black;
}
.active{
background: red;
}
Codepen: https ://codepen.io/miga89/full/owgZea/
我也將您的子組件轉換為無狀態組件,解決方案只是使用一個簡單的setInterval。
https://codepen.io/anon/pen/LLEyVo
const Child = ({ isActive }) => {
var childStyle = "basic";
if ( isActive ) childStyle += " active";
return <div className={ childStyle }></div>
}
class Parent extends React.Component {
constructor(props){
super(props);
this.state = {
firstChildActive : false,
secondChildActive : false,
thirdChildActive : false,
};
}
animateSequence(){
const TOTAL = 3;
const CHILD_DICT = ["firstChildActive","secondChildActive","thirdChildActive"];
let run = 0;
var setActive = setInterval( () => {
this.setState({ [CHILD_DICT[run]]: true });
run = run + 1;
if( run === TOTAL ) {
clearInterval(setActive);
}
}, 1000)
}
render() {
return (
<div className ="container">
<button onClick={ () => this.animateSequence() }>Run Sequence</button>
<Child isActive={this.state.firstChildActive }/>
<Child isActive={this.state.secondChildActive } />
<Child isActive={this.state.thirdChildActive }/>
</div>
);
}
}
ReactDOM.render(<Parent />,document.getElementById('app'));
您的此上下文在第一個setState的回調中無效。
var childDict = ["firstChildActive","secondChildActive","thirdChildActive"];
this.setState({[childDict[childNum]]: true}, function() {
應該
var childDict = ["firstChildActive","secondChildActive","thirdChildActive"];
this.setState({[childDict[childNum]]: true}, () => {
如果要在不使用按鈕的情況下執行此操作,請在原型中使用componentDidMount方法:
componentDidMount(){
this.animateSequence();
}
render() {
return (
<div className ="container">
<Child isActive={this.state.firstChildActive }/>
<Child isActive={this.state.secondChildActive } />
<Child isActive={this.state.thirdChildActive }/>
</div>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.