Radix One-Time Password Field - Values Not Persisting and Keyboard Navigation Broken
I recently integrated the Radix UI One-Time Password Field library into my project and am experiencing critical functionality issues:
-
Values not persisting: When typing digits, the focus correctly moves to the next input field, but the previously entered values disappear or don't display. The hidden input field doesn't seem to be capturing the complete OTP value.
-
Broken keyboard navigation:
- Tab key: Doesn't properly navigate between input fields
- Backspace/Delete: Fails to clear the current field or move focus back to the previous input as expected
The component appears to handle focus management but fails at value retention and standard keyboard interactions.
Environment:
- Package:
@radix-ui/react-one-time-password-field - Version: 0.1.8
- Framework: React
- OS: MacOS
- Browser: Google Chrome
Code Example:
<OneTimePasswordField.Root name="otp" >
<OneTimePasswordField.Input />
<OneTimePasswordField.Input />
<OneTimePasswordField.Input />
<OneTimePasswordField.Input />
<OneTimePasswordField.HiddenInput />
</OneTimePasswordField.Root>
https://github.com/user-attachments/assets/c9a3c0e1-02dd-4e49-ae72-044639725c96
Has anyone else experienced similar problems? Any guidance would be appreciated.
I'm also having the same issue, it seems to have started with react 19.2.
Here's a basic reproduction of the issue: https://github.com/kkuhnen/radix-otp-vite
@Guilherme-gso If you can use react 19.1, it should work.
This appears to be a bug in the new (unstable) collection implementation. Unclear at the moment why it surfaced in React 19.2, but I'm investigating a fix. It won't land in the next release but should be patched shortly after.
@chaance, managed to investigate this further?
As far as I understand the collection items do not update properly for the dispatch function of the OneTimePasswordField as can be seen in the following screenshots:
React 19.1:
React 19.2:
Perhaps the fact dispatch is defined by using the useEffectEvent is problematic as it uses the state value collection for example, the documentation of React states useEffectEvent shouldn't be used in this way as it could lead to unexpected problems:
Will try to see if useCallback fixes the issue,
Can pretty much confirm that seems to be the issue. Just change the useEffectEvent of OneTimePasswordField's dispatch function to useCallback and it works once more. Will make a PR for it.
I added a PR which fixes the issue.