I am a bit new to hooks, and ran into some unexpected behavior with useEffect()
.
I am using react-transition-group to build a component that slides content left or right depending on whether you are going forward or backward. It's based on this related answer.
The transition rendering looks like this:
// { isNext, count } -- see below
return (
<TransitionGroup
childFactory={(child) =>
React.cloneElement(child, {
classNames: isNext ? 'right-to-left' : 'left-to-right',
timeout: 1000,
})
}
>
<CSSTransition key={count} classNames="right-to-left" timeout={1000}>
<div className="slide">
Put your sliding content here. Change the key as the content changes.
The value of the key is unimportant Count: {count}
</div>
</CSSTransition>
</TransitionGroup>
);
And the CSS:
:root {
--duration: 1s;
}
.right-to-left-enter {
transform: translateX(100%);
}
.right-to-left-enter-active {
transform: translateX(0);
transition: all var(--duration) ease;
}
.right-to-left-exit {
transform: translateX(0);
}
.right-to-left-exit-active {
transform: translateX(-100%);
transition: all var(--duration) ease;
}
.left-to-right-enter {
transform: translateX(-100%);
}
.left-to-right-enter-active {
transform: translateX(0);
transition: all var(--duration) ease;
}
.left-to-right-exit {
transform: translateX(0);
}
.left-to-right-exit-active {
transform: translateX(100%);
transition: all var(--duration) ease;
}
The strange (to me) behavior that I'm seeing is that if I add useEffect()
to track the change in count
, the timing of the transition changes. A visible gap between the elements sliding in appears.
export const Slide = ({ count }) => {
const countRef = useRef();
useEffect(() => {
countRef.current = count;
}, [count]);
// Using [count] introduces a gap between the elements transitioned in and out
// If I remove count from deps, gap goes away (but logic is broken)
const isNext = count > countRef.current;
In case this is some kind of browser or local environment quirk, here's what I see when I have []
as the useEffect
dep:
And here's what I see when I add the [count]
as the useEffect
dep:
Note the white gap between the black elements as they slide across the screen.
What's going on here? How can I fix this so the animations are in sync?
Working example in CodeBlitz here.
Edit: Yes, I could make the white space go away in this example by just setting the container background to black, but (1) the real use case is not just a solid background and the gap can't be filled like that, and (2) I want to understand why useEffect
and deps behave this way. :)