尝试使用setTimeout更新时,useState表现出来

时间:2020-01-17 10:32:13

标签: javascript reactjs

我正在尝试使用setTimeout每6秒在true和false之间翻转一个useState。我使用此状态从div中添加/删除类-这将导致div在top: 0top: 100%之间切换(而transition负责动画处理)。

更具体地说,我有一个iPhone包装图像,其中包含内容图像。这个想法是,它将缓慢滚动到内容图像的底部,然后在6秒钟后(从它开始向下滚动的时间开始),然后无限长地开始向上滚动。但是,它根本无法正常工作。

我已经用onClick测试了它,它的工作原理完全符合我的预期。但是,使用setTimeout逻辑:

  • 状态总是 为假-即使我们将其设置为true,然后再进行记录
  • 从JSX的角度来看,状态始终为 true -始终添加类,这表​​示状态为true

当然,它不能为真和为假,它应该翻转其值。有人可以告诉我为什么它不起作用,或者告诉我为什么它以这种奇怪的方式起作用吗?

import React, { useState } from 'react';
import iphone from '../Images/iphone.png'

const Iphone = (props) => {
    const [isInitialised, setInitialised] = useState(false)
    const [animating, setAnimating] = useState(false)

    const startAnimation = () => {
        setAnimating(!animating); /* Even if I use `true`, it will log to the console as `false` */
        console.warn('animation change iphone!');
        console.warn(animating);
        console.warn(isInitialised); /* This also always logs as `false` */

        setTimeout(() => {
            startAnimation();
        }, 6000);
    }

    if (!isInitialised) {
        setInitialised(true);
        startAnimation();
    }

    return (
        <div className={`iphone align-mobile-center ${animating ? "iphone--animating" : ""}`} onClick={() => setAnimating(!animating)}>
            <img className="iphone__image" src={iphone} alt="An iPhone" />
            <div className="iphone__content">
                <img className="iphone__content-image" src={props.image} alt={props.alt} />
            </div>
        </div>
    )
}

export default Iphone;

我使用isInitialised,否则似乎会陷入无限循环。

1 个答案:

答案 0 :(得分:1)

您可以使用useEffect并将setTimeout带到外部。

import React, { useState } from 'react';
import iphone from '../Images/iphone.png'

const Iphone = (props) => {
    const [isInitialised, setInitialised] = useState(false)
    const [animating, setAnimating] = useState(false)
    useEffect(()=>{
       startAnimation();
    },[]);
    const startAnimation = () => {
        setAnimating(!animating); 
        console.warn('animation change iphone!');
        console.warn(animating);
        console.warn(isInitialised);
    }

    setTimeout(() => {
      if (!isInitialised) {
        setInitialised(true);
        startAnimation();
      }
    }, 6000);



    return (
        <div className={`iphone align-mobile-center ${animating ? "iphone--animating" : ""}`} onClick={() => setAnimating(!animating)}>
            <img className="iphone__image" src={iphone} alt="An iPhone" />
            <div className="iphone__content">
                <img className="iphone__content-image" src={props.image} alt={props.alt} />
            </div>
        </div>
    )
}

export default Iphone;