繁体   English   中英

我正在尝试使用钩子在 React 中重新启动 GIF 动画

[英]I am trying to restart a GIF animation in a React using hooks

我发现了类似的问题以及我试图修改的答案,我特别关注了这个问题 这里的目标是让 GIF 在每次显示此组件时重新启动。 我的示例代码已经经历了一两次迭代,这就是它现在的位置。

 import {useState, useEffect} from "react" import Footer from "../components/Footer"; import NavMenu from '../components/NavMenu' import {Box, Typography} from '@mui/material' import backgroundImage from '../assets/images/world-bg.png' import Logo from '../assets/images/chr-logo-white@2x.png' import landscape from '../assets/gifs/why-we-exist_1test.gif' import { Gif } from "@mui/icons-material"; const Exist = () => { const [gif, setGif] =useState('') const reloadGif = () => { setGif('') setTimeout(() => { setGif(landscape) }, 0) } useEffect(() => { reloadGif() return () => { setGif('') } },[] ) const styles ={ introContainer:{ height: '100%', width: '100vw', backgroundImage: `url(${backgroundImage})`, display: 'flex', flexDirection: 'column', alignContent: 'center', color:'white', textAlign:'center', justifyContent: 'center', alignContent:'center', flexShrink:0 } } return ( <Box sx = {styles.introContainer}> <NavMenu /> <Box > {gif !== '' && <img src={gif} alt="Logo"></img>} </Box> <Footer logo={false} back={'intro'} next={"home"}/> </Box> ) } export default Exist;

我希望我的 useEffect 会清除图像 src,然后再次设置它以强制重新渲染。 我看到的问题是,对于空的依赖数组,它不会触发重新渲染,但没有它,我会不断地重新渲染,但 GIF 仍然只播放一次。

这里的问题很可能是您没有明确的方法来重新触发使用效果来重新加载 Gif。

对此有多种解决方案,但这取决于您如何实现逻辑以显示和不显示您的组件。

正如您已经意识到的,只要将组件放在屏幕上,就会触发带有空依赖项数组的 useEffect。

作为解决方案,您需要检查当前如何将带有 gif 的组件呈现到屏幕上。 每当您想播放 gif 时,您都必须确保它是新添加到 DOM 中的。

附带说明:您的 useEffect 中不需要返回函数。

 const ParentComponent = () => { const [showChildComponent, setShowChildComponent] = useState(true) return ( <> <button onClick={() => {setShowChildComponent(!showChildComponent)}}> Click me to show or hide the child component </button> { showChildComponent && <ChildComponent /> } </> ) } const ChildComponent = () => { const [gif, setGif] =useState('') const reloadGif = () => { setGif('') setTimeout(() => { setGif(landscape) }, 0) } useEffect(() => { reloadGif() },[] ) return (<img src={gif} alt="Logo"></img>) }

您还可以在 prop/state 的帮助下重新触发 useEffect。 每次您的 showGif 状态更改时,都会重新触发以下 useEffect,您可以在想要播放 gif 时进行设置。

   const [retriggerGif, setRetriggerGif] = useState(true)

    useEffect(() => {
       reloadGif()
    },[retriggerGif]
    )

如果您无法安装/卸载您的组件

在您提到的评论中,您使用基于哈希的路由器,并且仅将您的组件包装在 RouterLink 中。

在这种情况下,您可以让 useEffect 依赖于路由器的哈希值,并始终重新运行哈希值更改:

这当然取决于您使用的路由器,但总有一种方法可以获取当前活动的路径并以某种方式散列。

在 react-router 中,你可以像这样通过useHistory()钩子获取history对象:

const history = useHistory() 

useEffect(() => { 
    // check that you are at the correct hash 
    if(history.hash === 'header') { 
        reloadGif() 
    } 
}, [history]) 

以@Carolin 的回答为起点。 我能够想出一个解决方案,仍然感觉很糟糕,但它有效。

import {useEffect} from "react"
import Footer from "../components/Footer";
import NavMenu from '../components/NavMenu'
import {Box} from '@mui/material'
import backgroundImage from '../assets/images/world-bg.png'
import landscape from '../assets/gifs/why-we-exist_1test.gif'




const Exist = ({viewCount, handleView}) => {


useEffect(() => {
    return () => {
     return handleView(viewCount + 1)
    }
},[])

const styles ={
    introContainer:{
        height: '100%',
        width: '100vw',
        backgroundImage: `url(${backgroundImage})`,
        display: 'flex',
        flexDirection: 'column',
        alignContent: 'center',
        color:'white',
        textAlign:'center',
        justifyContent: 'center',
        alignContent:'center',
        flexShrink:0
    }
}

return (
    <Box sx = {styles.introContainer}>
        <NavMenu />
        <Box >
        {viewCount %2 === 0 && <img src={landscape + "?=" + Date.now()} alt="Logo"></img>}
        {viewCount %2 !== 0 && <img src={landscape + "?=" + Date.now()} alt="Logo"></img>}
        </Box>
        <Footer logo={false} back={'intro'} next={"home"}/>
    </Box>
  )
}

export default Exist;

其中 viewCount 和 handleView 是来自父组件的const [count, setCount]=useState(0)道具

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM