Solved: via local state and via dom manipulation
After a lot of trial and error :-D I came up with two solutions.
1. Via local state flag
As I understand, my first attempts were faulty because I didn't account for the initial events, that were fired also on Inertia first load. So, I improved the first approach using js template tags and initializing local state at null.
// solved via local state flag
function LayoutWithPageTransition(Page) {
const [transitioning, setTransitioning] = useState(null)
useEffect(() => {
Inertia.on('start', () => setTransitioning(true))
Inertia.on('finish', () => setTransitioning(false))
}, [])
const pageTransition = useMemo(
() => `animate__animated ${
transitioning ? 'animate__fadeOut' : 'animate__fadeIn'
}`, [transitioning])
return <div className={pageTransition}>{Page}</div>
}
2. Via direct dom manipulation
I initialized the transitioned element with the entry animation class, then toggled both classes in a single handler (for convenience).
// solved via direct dom manipulation
function LayoutWithPageTransition(Page) {
const transitionedEl = useRef(null)
const handleTransition = useCallback(() => {
transitionedEl.current.classList.toggle('animate__fadeIn')
transitionedEl.current.classList.toggle('animate__fadeOut')
}, [])
useEffect(() => {
Inertia.on('start', handleTransition)
Inertia.on('finish', handleTransition)
}, [])
return <div
ref={transitionedEl}
className='animate__animated animate__fadeIn'>
{Page}
</div>
}
Conclusion
Both solutions achieve the same effect, but I prefer using the local state flag because I'm concerned with code readability in the direct dom manipulation solution.
I would love to read some other approach and opinions.
Kindest regards, GdS
PS: Since I can already foresee myself reusing the state solution on every layout, I've built an npm package on-the-fly: use-inertia-simple-page-transition