javascript - 我正在尝试使用钩子在 React 中重新启动 GIF 动画
问题描述
我发现了与我试图修改的答案类似的问题,我特别关注了这个问题。这里的目标是让 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>)
}
您还可以在道具/状态的帮助下重新触发 useEffect。每当您的 showGif 状态发生变化时,都会重新触发以下 useEffect,您可以在想要播放 gif 时进行设置。
const [retriggerGif, setRetriggerGif] = useState(true)
useEffect(() => {
reloadGif()
},[retriggerGif]
)
如果您无法安装/卸载您的组件
In the comments you mentioned you use a hash based router and only wrap your component in a RouterLink.
In this case you could make your useEffect depend on the hash of your router and always rerun of the hash changes:
This of course depends on what router you are using but there is always a way to get the currently active path and hash somehow.
In react-router you e.g. can get the history
object through the useHistory()
hook like this:
const history = useHistory()
useEffect(() => {
// check that you are at the correct hash
if(history.hash === 'header') {
reloadGif()
}
}, [history])
推荐阅读
- java - 当我们通过停止mssql数据库强制拦截批处理执行时如何查找加载记录的状态
- docker - Docker - Alpine Elixir 容器具有不可满足的约束
- python - 什么时候numba有效?
- java - 如何修复 Android Studio 中的“gradle 项目同步失败的基本功能将无法正常工作”错误
- node.js - 调用应用程序时出现 HTTP 错误 426
- ruby-on-rails - Webpack Config Found 没有配置条目
- laravel-5.8 - 如何在 Laravel Envoy 脚本中设置密码?
- css - 是否可以将位置粘性行为限制在特定的网格行中?
- c++11 - 如何根据类中的编译时常量创建类型别名?
- python - 在 Robotframework-AutoItLibrary 中控制 Click 什么都不做