airjp73 / rvf

Easy form validation and state management for React and Remix
https://rvf-js.io
MIT License
840 stars 66 forks source link

[Bug]: value of useControlField not updating on change #272

Closed sergiocarneiro closed 1 year ago

sergiocarneiro commented 1 year ago

Which packages are impacted?

What version of these packages are you using?

Please provide a link to a minimal reproduction of the issue.

https://codesandbox.io/s/youthful-leaf-73pitm?file=/app/routes/index.tsx

Steps to Reproduce the Bug or Issue

  1. Write something in the name input
  2. Check the console
  3. (No messages exist saying "Name changed to ...")

Expected behavior

I expect the value of useControlField to behave just like useState, so it triggers re-renders and I can listen to changes with useEffect.

Screenshots or Videos

No response

Platform

Additional context

Changes made

I only added a useControlField and a useEffect to the route component, everything else is the starter bug repro.

Sandbox not working

I couldn't run and preview the sandbox, even without changing anything. But I tested locally.

airjp73 commented 1 year ago

Hi!

This is one place where we're a little different from other form libraries. In your reproduction, you're responding to the changes to the name value, but you're not actually calling setName anywhere, which is why nothing is updating.

You're example looks closest to the "Occasional field tracking" example in the docs here. There are a couple other examples on this page that might be worth reading, as well. Here's the code snippet from the one I mentioned:

export const MyForm = () => {
  const [value, setValue] = useControlField(
    "myField",
    "myForm"
  );

  useEffect(() => {
    // Now we can update the value of the field
    // for whatever reason we need.
    setValue("Some value");
  });

  return (
    <ValidatedForm validator={myValidator} id="myForm">
      <MyInput
        name="myField"
        // This assumes your input component
        // has a `value` and `onChange` prop
        value={value}
        onChange={(e) => setValue(e.target.value)}
      />
    </ValidatedForm>
  );
};

I hope that helps!

sergiocarneiro commented 1 year ago

Hi!

Thanks for the clarification. I assumed the changes to form fields were being automatically propagated to these hooks.

In my actual use case I am calling setName, but it's from another component that wraps the input and handles this logic, ValidatedInput. And I hoped I could listen to changes on the value using the hook instead of a per-component onChange callback.