【问题标题】:Issues when trying to loop images in React with useState [duplicate]尝试使用 useState 在 React 中循环图像时出现问题 [重复]
【发布时间】:2021-08-30 15:39:54
【问题描述】:

我正在尝试使用 React 制作包含几张图片的循环。

我使这个合乎逻辑,对我来说,它应该有效,但它没有! 我用 javascript 对一个 html 页面做了同样的逻辑,但是在 React 组件中它不起作用。

export default function AnimatedImage() {
    const [imageRoute, setImageRoute] = useState('source1')
    const [frame, setFrame] = useState(1)
    
    const imagesPath = [
        "source1",
        "source2",
        "source3",
        "source4"
    ]
    
    function handleAnimation(){
        setImageRoute(imagesPath[frame])

        if (frame === 3)
            setFrame(0)

        setFrame(frame + 1)
    }

    setInterval(handleAnimation, 300);
   
    return (
        <img src={imageRoute} />
    )
}

我的图像本身有一些问题,有时它会消失并显示“未找到图像”的图标,然后在几毫秒后又会再次出现。有时间隔会变得疯狂并开始非常快地循环忽略设置的时间。

这只发生在 React 中。

这里没有任何意义 有人可以帮忙吗?

【问题讨论】:

    标签: javascript reactjs use-state


    【解决方案1】:

    由于您的 setInterval 调用在您的渲染函数中,因此每次修改组件的状态时都会创建一个新计时器。最终,您将有许多计时器同时运行并相互踩踏以更改图像源。您应该使用useEffect hook 确保仅在组件挂载时设置一次定时器,并在组件卸载时清除间隔。

    此外,我还将使用单个状态来跟踪正在显示的图像,以避免您的帧和源不同步。

    const imagesPath = [
        "source1",
        "source2",
        "source3",
        "source4"
    ]
    
    export default function AnimatedImage() {
        const [frame, setFrame] = useState(0)
    
        useEffect(() => {
            const handleAnimation = () => {
                setFrame(frame => (frame + 1) % imagesPath.length)
            }
            const interval = setInterval(handleAnimation, 300) // 300 ms is pretty short. Did you mean 3000?
            return () => clearInterval(interval)
        }, [])
       
        return (
            <img src={imagesPath[frame]} />
        )
    }
    

    const { useState, useEffect } = React;
    
    const imagesPath = [
        "https://via.placeholder.com/150/E34234/FFF",
        "https://via.placeholder.com/150/458E00/FFF",
        "https://via.placeholder.com/150/8B65E7/FFF",
        "https://via.placeholder.com/150/C06500/FFF"
    ];
    
    function AnimatedImage() {
        const [frame, setFrame] = useState(0)
    
        useEffect(() => {
            const handleAnimation = () => {
                setFrame(frame => (frame + 1) % imagesPath.length)
            }
            const interval = setInterval(handleAnimation, 300) // 300 ms is pretty short. Did you mean 3000?
            return () => clearInterval(interval)
        }, [])
       
        return (
            <img src={imagesPath[frame]} />
        )
    }
    
    ReactDOM.render(<AnimatedImage />, document.querySelector("#animated-image-container"));
    <script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
    <div id="animated-image-container"></div>

    【讨论】:

      【解决方案2】:

      它与钩子规则有关。 https://reactjs.org/docs/hooks-rules.html 尝试在手柄动画中使用箭头功能

      const handleAnimation = () => { /** your code */}
      

      【讨论】:

        猜你喜欢
        • 2021-03-16
        • 1970-01-01
        • 2021-01-31
        • 1970-01-01
        • 2020-07-10
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多