Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React 19 Actions + RAC Form aren't working properly due to automatic form reset #6830

Open
pawelblaszczyk5 opened this issue Aug 5, 2024 · 2 comments

Comments

@pawelblaszczyk5
Copy link

pawelblaszczyk5 commented Aug 5, 2024

Provide a general summary of the issue here

React 19 actions has behavior (that was added in canary cycle after Form component in RAC and documentation around it) that it automatically resets form after submission to mimic default browser behavior - PR Link.

I spotted two things that it's breaking while using RAC Form:

  1. This form reset sets the value to defaultValue that was initially passed, not to the current defaultValue one:

let resetValue = useRef(initialValue);
let handleReset = useEffectEvent(() => {
if (onReset) {
onReset(resetValue.current);

This isn't working correctly with the recommended pattern by React that defaultValue represent canonical state from the server.

  1. Errors passed from action state to validationErrors prop on Form aren't properly used because the Form validation state is discarded with form reset event. I'm not 100% sure but I feel like it's here in code:

let onReset = useEffectEvent(() => {
state.resetValidation();
});

This breaks the pattern where action returns some additional errors that can be created only from the server. This is also the pattern used in the RAC docs.

🤔 Expected Behavior?

React 19 patterns where you use actions to drive both canonical form state and form errors works correctly. You use defaultValue with the formData to prevent the values from being reset and you can pass errors to Form component and they're properly displayed.

😯 Current Behavior

React 19 automatic reset behavior breaks both form state and errors state

💁 Possible Solution

I'm not sure here

🔦 Context

I'm building an SPA app with React 19 RC version and noticed that actions doesn't really work properly with RAC form handling

🖥️ Steps to Reproduce

I created a reproduction:

https://stackblitz.com/edit/vitejs-vite-edgrdn?file=src/App.tsx,package.json

There're three forms rendered:

  1. Using actions without RAC, example of how React actions should be used. The error is properly displayed after submission, the value is being keep because of the defaultValue being updated. Obviously this misses RAC a11y stuff and all the goodies
  2. Using actions with RAC, you can observe that the error isn't properly being displayed after submission and the value is being reset despite defaultValue being updated
  3. RAC without actions, using plain state, just to confirm that it works in React 19 and how +- it's supposed to behave

Version

RAC 1.3.1

What browsers are you seeing the problem on?

Firefox, Chrome, Safari, Microsoft Edge

If other, please specify.

No response

What operating system are you using?

MacOS Sonoma 14.5, Windows 11

🧢 Your Company/Team

No response

🕷 Tracking Issue

No response

@snowystinger
Copy link
Member

Thanks for the issue and all the detailed information. Someone will look into this soon. Thank you for your patience.

@snowystinger
Copy link
Member

snowystinger commented Aug 22, 2024

Had a little look into this today. In terms of reset and defaultValue, it's even more complex. Fields such as NumberField which actually take a number as their value, cannot be restored by React since the form data is all strings, and it's unlikely a user would be able to always know how to parse those strings, which is why we'll sometimes recommend a hidden input that you maintain with the value you want to go to the server.

We listen for reset already in our form elements, as you noted on useFormReset. Right now that directly calls setState with the first value that the field had. We'd need to get the value off corresponding ref to the input, then apply whatever transformation to get it into a state we understand.

We can't rely on tracking the defaultValue as users may update it too much, so we wouldn't want to be responsive to it. But on the flip side, if we try to only track the defaultValue in a ref, then we have to do that in a layout effect, which would be too late for the reset event. We would always be one state behind.

As for the discarded error on reset, I'm really not sure what to do about that one. I don't quite follow how React envisions getting rid of the error or what the purpose of a Reset button in a form would now be. I tried adding a Reset button to your example, it doesn't do anything. It doesn't clear the errors and it doesn't reset to the actual default of empty string.

I both hope and do not hope that whatever is holding up React 19 is not related to this. Hard to predict what we should do when React 19 isn't actually out yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants