gpbl / gpbl/react-day-picker

`animate` glitches when `month` is controlled and the parent rerenders during navigation

Open
#2,935 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
TypeScript
Stars
6.9k
Forks
780
Avg merge
2d 3h
Merged PRs (30d)
3

Description

## Summary

When `DayPicker` is used with `animate` and a controlled `month` prop, the month transition can glitch if the parent rerenders during `onMonthChange`.

This is easy to reproduce in the Docusaurus playground when `month` is synced to external state / query-string state, but it looks like a library-level robustness issue rather than a docs-only issue.

## Reproduction

```tsx
function ControlledAnimatedCalendar() {
const [month, setMonth] = useState(new Date(2026, 3, 1));
const [tick, setTick] = useState(0);

return (
{
setMonth(nextMonth);
setTick((x) => x + 1); // simulate external rerender / router update
}}
/>
);
}
```

## Actual behavior

The transition can briefly flicker, jump, overlap, or appear to reset mid-flight.

https://github.com/user-attachments/assets/9514497c-c1c0-4dc8-b33b-3979131dc2ee

## Expected behavior

Animated month transitions should remain stable when `month` is controlled, even if the parent rerenders during `onMonthChange`.

https://github.com/user-attachments/assets/6fce5b66-c73e-41dd-af69-ba641e35d79a

## Notes

- The Docusaurus playground makes this easy to trigger because it syncs props to the URL.
- A plain Vite example where month navigation stays internal to `DayPicker` does not show the same glitch.
- This suggests the issue is related to controlled animated navigation under extra rerender pressure.

## Suspected cause

`src/useAnimation.ts` appears to update animation snapshots/refs on every render. In controlled mode, parent rerenders during an ongoing transition may cause the animation bookkeeping to be refreshed from an already animating tree, which can desync the transition state from the DOM.

## Possible fixes

1. Only set up animation state when the displayed month actually changes, not on every rerender.
2. Keep one stable snapshot per transition and avoid overwriting it while an animation is active.
3. Add a regression test for `animate` + controlled `month` + parent rerender in `onMonthChange`.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.