React点击切换props传入的图片时如何添加平滑过渡动画效果?
解决方案
最小改动实现过渡效果(纯CSS+少量React调整)
你当前的首次进入视口的过渡逻辑已经可用,只需要做3处调整就能实现点击切换时的淡入效果:
- 父组件
<App.js/>调整
给<Message/>组件传入key属性为当前的index值,React遇到key变化时会重新挂载组件,触发首次进入的过渡逻辑:
// App.js 中调用Message的部分修改为 <Message key={index} visible={visible} img={imgArray[index].img} label={imgArray[index].label} imgAlt={imgArray[index].imgAlt} />
- 补充CSS样式
给图片和标题都加上过渡规则,你可以直接在全局CSS文件中添加以下代码(如果已经写过图片的过渡规则可以忽略对应部分):
/* 给标题加和图片同款的过渡效果 */ .msg-lbl { opacity: 0; transform: translateY(10px); transition: all 0.5s ease; } .msg-lbl.is-visible { opacity: 1; transform: translateY(0); } /* 图片过渡规则 */ .inline-photo { opacity: 0; transform: translateY(10px); transition: all 0.5s ease; } .inline-photo.is-visible { opacity: 1; transform: translateY(0); }
- 子组件
<Message.jsx/>调整
给标题也加上is-visible的类名判断:
function Message(props){ return ( <div className="msg-div-index msg-div-height my-5"> <h3 className="text-start fs-5 m-0 px-2">Make us</h3> {/* 给h2加动态类名 */} <h2 className={"msg-margin msg-lbl" + (props.visible ? " is-visible" : "")}>{props.label}</h2> <img src={props.img} className={"img-fluid msg-img-index msg-img-opacity msg-img-border inline-photo" + (props.visible ? " is-visible" : "")} alt={props.imgAlt}></img> </div> ) } export default Message
如果需要“先淡出再淡入”的连贯过渡效果
可以在子组件中加一个内部状态监听props变化,实现切换时的连贯过渡:
import { useState, useEffect } from 'react' function Message(props){ const [show, setShow] = useState(false) // 监听图片变化,每次切换先隐藏再显示 useEffect(() => { setShow(false) const timer = setTimeout(() => { setShow(true) }, 300) // 和CSS里设置的淡出时长保持一致 return () => clearTimeout(timer) }, [props.img]) const isVisible = props.visible && show return ( <div className="msg-div-index msg-div-height my-5"> <h3 className="text-start fs-5 m-0 px-2">Make us</h3> <h2 className={"msg-margin msg-lbl" + (isVisible ? " is-visible" : "")}>{props.label}</h2> <img src={props.img} className={"img-fluid msg-img-index msg-img-opacity msg-img-border inline-photo" + (isVisible ? " is-visible" : "")} alt={props.imgAlt}></img> </div> ) } export default Message
对应把CSS中的过渡时长调整为0.3s即可匹配逻辑。
代码优化建议
- 点击切换逻辑可以简化,不用手动判断数组边界:
// 原来的handleClick替换为 function handleClick(){ setIndex(prev => (prev + 1) % imgArray.length) }
useOnScreen钩子中的console.log(visible)是调试代码,上线前可以删除。imgArray可以移到App组件外部,避免每次组件渲染都重新创建数组。
内容的提问来源于stack exchange,提问作者E.K.Garcia
相关产品推荐
相关产品推荐

