I have two child components, an image gallery and a hidden components which will display the clicked image of the gallery at full size.
const [selectedIndex, setSelectedtIndex] = useState(0);
const [galleryVisible, setGalleryVisible] = useState(false);
const FirstComponent = () => {
return (
<div className={'gallery-container'}>
<div class='img fade-1' onClick={() => handleClick(1)}>Image 1</div>
<div class='img fade-2' onClick={() => handleClick(2)}>Image 2</div>
<div class='img fade-3' onClick={() => handleClick(3)}>Image 3</div>
[...]
</div>
)
}
const handleClick = (index) => {
setSelectedtIndex(index)
setGalleryVisible(true)
}
const SecondComponent = ({ index }) => {
return (
<div className={`selected-img`}>Selected : {index} (But the fading animation shouldn't restart è_é)</div>
)
}
return (
<>
<FirstComponent/>
{galleryVisible &&
<SecondComponent index={selectedIndex} />
}
</>
)
The issue is that I also have a fade-in animation on the first component, and every time I click on an image to display the second component, that animation resets due to the rerender of react on state change.
&.fade-1 {
animation-delay: 0s
}
&.fade-2 {
animation-delay: 0.5s
}
&.fade-3 {
animation-delay: 1s
}
I don't know how can I only change the second component when the state is changed from a click on the first one... I tried to play with useMemo but couldn't get it to work.
Here is a codepen reproducing the issue : https://codepen.io/disgallion/pen/zYjqPBE
CodePudding user response:
Move the first component outside of App
and pass handleClick
to its props:
const FirstComponent = ({handleClick}) => {
return (
<div className={'gallery-container'}>
<div class='img fade-1' onClick={() => handleClick(1)}>1</div>
<div class='img fade-2' onClick={() => handleClick(2)}>2</div>
<div class='img fade-3' onClick={() => handleClick(3)}>3</div>
</div>
)
}
const App = () => {
const [selectedIndex, setSelectedtIndex] = useState(0);
const [galleryVisible, setGalleryVisible] = useState(false);
const handleClick = (index) => {
console.log('click')
setSelectedtIndex(index)
setGalleryVisible(true)
}
const SecondComponent = ({ index }) => {
return (
<div className={`selected-img`}>Selected : {index} (But the fading animation shouldn't restart è_é)</div>
)
}
return (
<>
Click on an image to open the fullsize gallery:
<FirstComponent handleClick={handleClick} />
{galleryVisible &&
<SecondComponent index={selectedIndex} />
}
</>
)
}
ReactDOM.render(<App />,
document.getElementById("root"))
Now the state change of App
will not trigger a re-render in FirstComponent