I've got some animations that I'm trying to get to work using setTimeouts and for some reason they are firing over and over again until the end of time. I've got a reducer that holds all of my booleans and an action that toggles them, but the problem is that the action is being fired regardless of whether or not the condition is true in the setTimeouts. I've looked in the chrome console and confirmed this to be true, but I don't know why. I'll place my code below.
type LandingPagePropTypes = {
displayCommandText: boolean,
displayInstallText: boolean,
displayAboutText: boolean,
displayEnterText: boolean,
displayWelcomeHeader: boolean,
togglePropertyInState: (propertyName: string) => void,
togglePopUpModal: (message: string) => void,
};
const LandingPage = (
{
displayWelcomeHeader,
displayCommandText,
displayAboutText,
displayInstallText,
displayEnterText,
togglePropertyInState,
togglePopUpModal,
}: LandingPagePropTypes,
) => {
setTimeout(() => {
if (!displayCommandText) {
togglePropertyInState('displayCommandText');
}
}, 1000);
setTimeout(() => {
if (!displayInstallText) {
togglePropertyInState('displayInstallText');
}
}, 3000);
setTimeout(() => {
if (!displayAboutText) {
togglePropertyInState('displayAboutText');
}
}, 4000);
setTimeout(() => {
if (!displayEnterText) {
togglePropertyInState('displayEnterText');
}
}, 5000);
setTimeout(() => {
if (!displayWelcomeHeader) {
togglePropertyInState('displayWelcomeHeader');
}
}, 1000);
return (
<div className="landing-page-container">
<MediaQuery maxWidth={767}>
<MobileLandingPage
displayWelcomeHeader={displayWelcomeHeader}
/>
</MediaQuery>
<MediaQuery minWidth={768}>
<DesktopLandingPage
displayCommandText={displayCommandText}
displayInstallText={displayInstallText}
displayAboutText={displayAboutText}
displayEnterText={displayEnterText}
togglePopUpModal={togglePopUpModal}
/>
</MediaQuery>
</div>
);
};
setTimeout()
belongs in the componentDidMount or componentDidUpdate methods. You will also need a clearTimeout
in the componentWillUnmount method to cancel the timeout or you'll get a setState on an unmounted component
warning if you unmount the component before the timeout fires. Here's a simplified example.
class SomeComp extends Component {
constructor() {...}
_startAnimation = timeout => {
this.enterAnimation = setTimeout(
() => this.setState({ mode: 'entered' }),
timeout
)
}
componentDidMount() {
const timeout = someNum
this._startAnimation(timeout)
}
componentWillUnmount() {
!!this.enterAnimation && clearTimeout(this.enterAnimation)
}
render() {...}
}
I wanted to update on what I ended up doing. I want to add that I'm using Flowtype and eslint paired with AirBnB rules so I had to restructure things a bit to satisfy both of them.
class LandingPage extends Component <LandingPagePropTypes> { constructor(props: LandingPagePropTypes) { super(props); const { togglePropertyInState } = this.props; this.setCommandText = setTimeout(() => togglePropertyInState( 'displayCommandText' ), 1000); this.setInstallText = setTimeout(() => togglePropertyInState( 'displayInstallText' ), 3000); this.setAboutText = setTimeout(() => togglePropertyInState( 'displayAboutText' ), 4000); this.setEnterText = setTimeout(() => togglePropertyInState( 'displayEnterText' ), 5000); this.setWelcomeHeader = setTimeout(() => togglePropertyInState( 'displayWelcomeHeader' ), 1000); } componentWillUnmount() { const { displayCommandText, displayInstallText, displayAboutText, displayEnterText, displayWelcomeHeader, } = this.props; if (displayCommandText) { clearTimeout(this.setCommandText); } if (displayInstallText) { clearTimeout(this.setInstallText); } if (displayAboutText) { clearTimeout(this.setAboutText); } if (displayEnterText) { clearTimeout(this.setEnterText); } if (displayWelcomeHeader) { clearTimeout(this.setWelcomeHeader); } } setCommandText: TimeoutID; setInstallText: TimeoutID; setAboutText: TimeoutID; setEnterText: TimeoutID; setWelcomeHeader: TimeoutID; render() { const { displayWelcomeHeader, displayCommandText, displayAboutText, displayInstallText, displayEnterText, togglePopUpModal, } = this.props; return ( <div className="landing-page-container"> <MediaQuery maxWidth={767}> <MobileLandingPage displayWelcomeHeader={displayWelcomeHeader} /> </MediaQuery> <MediaQuery minWidth={768}> <DesktopLandingPage displayCommandText={displayCommandText} displayInstallText={displayInstallText} displayAboutText={displayAboutText} displayEnterText={displayEnterText} togglePopUpModal={togglePopUpModal} /> </MediaQuery> </div> ); } }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.