React模态框内点击前后按钮时Fade动画失效问题求助
Hey there! I see the issue you're facing—your modal's content updates when clicking Prev/Next, but the react-reveal Fade animations don't re-trigger. Let's break down why this happens and fix it.
Why the Animations Aren't Triggering
The <Fade> component from react-reveal only plays its animation when the component mounts by default. When you switch profiles via Prev/Next, you're updating the profile state, but the <Fade> components themselves don't unmount and re-mount—they just update their inner content. That's why the animations don't run again.
Solution 1: Force Re-Mount with a Unique key (Simplest Fix)
The easiest way to trigger the animation again is to give each <Fade> component a unique key that changes whenever the active profile changes. When React sees a new key, it treats the component as a new instance, unmounting the old one and mounting the new one—which triggers the Fade animation.
Modify your modal code like this:
<Modal open={open} onClose={onCloseModal} center classNames={{ overlay: 'customOverlay', modal: 'customModal', }}> <h2>Simple centered modal</h2> {/* Use profile.title as a unique key to force re-mount */} <Fade bottom delay={300} key={profile.title}> <h5>{profile.title}</h5> </Fade> <Fade bottom delay={800} key={`description-${profile.title}`}> <p>{profile.description}</p> </Fade> <div className="btn-group"> <button className="btn" onClick={handlePrev}>Prev</button> <button className="btn" onClick={handleNext}>Next</button> </div> </Modal>
Alternatively, you can use the index state as the key (since it changes with each profile switch):
<Fade bottom delay={300} key={`title-${index}`}> <h5>{profile.title}</h5> </Fade> <Fade bottom delay={800} key={`description-${index}`}> <p>{profile.description}</p> </Fade>
Solution 2: Use react-reveal's trigger Prop (Alternative Approach)
If you prefer not to force component re-mounts, you can use the trigger prop provided by react-reveal to manually control when the animation plays. This involves adding a state to toggle the trigger whenever you switch profiles.
- Add a new state to track animation triggers:
const [animateModal, setAnimateModal] = useState(false);
- Update your
handlePrevandhandleNextfunctions to toggle this state:
const handlePrev = () => { if(index > 0){ let i = index - 1; setProfile(profiles[i]); setIndex(i); setAnimateModal(prev => !prev); // Toggle to trigger animation } } const handleNext = () => { if(index < profiles.length - 1){ let i = index + 1; setProfile(profiles[i]); setIndex(i); setAnimateModal(prev => !prev); // Toggle to trigger animation } }
- Add the
triggerprop to your<Fade>components:
<Fade bottom delay={300} trigger={animateModal}> <h5>{profile.title}</h5> </Fade> <Fade bottom delay={800} trigger={animateModal}> <p>{profile.description}</p> </Fade>
Full Modified App.js (With Solution 1)
Here's the complete working code with the first solution implemented:
import React, {useState} from 'react'; import Fade from 'react-reveal/Fade'; import 'react-responsive-modal/styles.css'; import { Modal } from 'react-responsive-modal'; import "./App.css"; const App = () => { const [open, setOpen] = useState(false); const [index, setIndex] = useState(0); const [profile, setProfile] = useState({}); const [profiles, setProfiles] = useState([ {title: "First title", description: "It is first description"}, {title: "Second title", description: "It is second description"}, {title: "third title", description: "It is third description"}, ]); const onOpenModal = (item) => { setOpen(true); setProfile(item); } const onCloseModal = () => setOpen(false); const handlePrev = () => { if(index > 0){ let i = index - 1; setProfile(profiles[i]); setIndex(i); } } const handleNext = () => { if(index < profiles.length - 1){ let i = index + 1; setProfile(profiles[i]); setIndex(i); } } return ( <div> <h1>Application..............</h1> <div className="container"> { profiles.map((p, i) => ( <div key={i} className="item" onClick={() => onOpenModal(p)}> <h1>{p.title}</h1> </div> )) } </div> <Modal open={open} onClose={onCloseModal} center classNames={{ overlay: 'customOverlay', modal: 'customModal', }}> <h2>Simple centered modal</h2> <Fade bottom delay={300} key={profile.title}> <h5>{profile.title}</h5> </Fade> <Fade bottom delay={800} key={`desc-${profile.title}`}> <p>{profile.description}</p> </Fade> <div className="btn-group"> <button className="btn" onClick={handlePrev}>Prev</button> <button className="btn" onClick={handleNext}>Next</button> </div> </Modal> </div> ) } export default App;
Now when you click Prev/Next, the Fade animations will play each time the modal content updates!
内容的提问来源于stack exchange,提问作者arjun sah

