menu

Popmotion

Help and discussion for Popmotion's animation libraries: Popmotion, Pose, React Pose, React Native Pose, etc

Channels
Team

React Router + React Pose slide in/out with "POP" or "PUSH" direction

July 19, 2019 at 11:40am

React Router + React Pose slide in/out with "POP" or "PUSH" direction

July 19, 2019 at 11:40am

I've been having this issue for over a month, getting back to it with new ideas over and over, but I can't wrap my head around a solution. There must be one out there, this is trivial!

My goal is to normally slide pages in from left and slide out to right. When it reverses (user click back button or history notices a route has been popped) the page should exit to the right and next route should enter from left (opposite).

Everything works, but when I PUSH a route and then POP a route, the next page will both exit to right and enter from right. The entering page uses an old pose before it has time to update. If I POP another time, it then works correctly, and the new page slides from left while the old page exits to right. It's only the first time I change with a POP. I'm very dependent on the const reverse value. The component only renders once when I change route and reverse = true the first time I click POP.

I have an AnimatedSwitch component like this

export const AnimatedSwitch = ({ location, children, ...rest }) => {
const clickedBack = useSelector(state => state.interfaceReducer.clickedBack);
const routePopped = useSelector(state => state.routeReducer.routePopped);
const reverse = clickedBack || routePopped;
const onRest = () => {
clickedBack && dispatch(toggleClickedBackButton(false));
}
return (
<PoseGroup
animateOnMount={true}
preEnterPose={reverse ? "leftSide" : "rightSide"}
exitPose={reverse ? "rightSide" : "leftSide"}
onRest={onRest}
reverse={reverse}
>
<ContextRouteAnimation poseKey={`${reverse}-${location.pathname}`} key={location.pathname} reverse={reverse}>
<Switch location={location} {...rest}>
{children}
</Switch>
</ContextRouteAnimation>
</PoseGroup>
)
}

And this is the ContextRouteAnimation pose component:

const ContextRouteAnimation = posed.div({
enter: {
opacity: 1,
x: "0%",
transition: {
type: "tween",
ease: "easeInOut",
duration: TIMING.SLOW,
},
},
leftSide: {
x: "-100%",
opacity: 0,
transition: {
type: "tween",
ease: "easeInOut",
duration: TIMING.SLOW,
},
},
rightSide: {
x: "100%",
opacity: 0,
transition: {
type: "tween",
ease: "easeInOut",
duration: TIMING.SLOW,
},
},
});

I've tried multiple things such as

  • Pass reverse down to ContextRouteAnimation and use preEnter + exit poses.
  • Set pose directly on ContextRouteAnimation
  • Store component as state and only update it after new pose is updated, and then trigger another render
No messages yet