Formik - Update initial values after API call - reactjs

I'm getting my inputs dynamically from an API call based on a change in select input, but when I try to add to the initial values of Formik, it always gives me an error ...
Warning: A component is changing an uncontrolled input of type text to be controlled.
And it doesn't help if I set enableReinitialize={true} to Formik.
However, if I generated the inputs from a local JSON or object, the error goes away.
What am I doing wrong here ...
https://codesandbox.io/s/test-dynamic-inputs-with-formik-xr9qg
The form submits fine though.

Better use enableReinitialize={true}. This is official Formik API.
You can check this issue

If anyone is facing the same issue, I just found the solution ...
You have to set value={field.value || ''} in the input inside the TextInput component or whatever type you're using in order to fix this issue.

I had a complex, dynamic form and also came across this issue. There are a few things that I'd recommend for anyone debugging this issue in the future:
Set value for your Field component--like Ruby does above.
Ensure that your Formik component has a uniquely identifying key.
Track and debug your initialValues and ensure that all fields are accounted for. You shouldn't have to set the field value like Ruby does--so long as your initialValues object accounts for all of the fields. However, my form dynamically changed Field components--and Ruby's solution is the only one that worked.
If your form is not dynamic--I think it might be best to check your initialValues object first before implementing Ruby's solution. Formik should be taking care of those values for you--which is why it's such an awesome tool.

i've checked with enableReinitialize={true}. But its not working as much as expected. so wrote a useEffect like
useEffect(() => {
formik.setFieldValue('query_string', active?.query);
}, [active])
it's worked !

Related

Formik Resetting the Initial Values using Yup validation with it

I have a piece of code where Formik is used in the #React app with #Typescript and Yup validation. The problem I am facing is that on setting the values in a Select element it does not change the value at all or perhaps it immediately resets the value to the initial value as given in the Formik initial value object. What should I do about it? (No code is available here. But hopefully)
This issue is resolved.
In my case enableReinitialize is the culprit.
It was just the enableReinitialize property in the initial Values object set to true. You just need to remove this and you are good to go. I tried dozens of patches to cope with the problem and due to this property, each and every property was not working according to the logic. I also used #MUI #DatePicker #MUIDatePicker which was having issues because of this one property.
Hope it helps many others.
#Coding

React Hook Form - Does not set dependent select field value properly in edit mode

I am implementing a form in react using react hook form, The form has two select fields country and states.
Second field changes the option based on the selection in first field.
Please see the below sandbox for more details
Creating/submitting the record works perfectly fine.
The problem is: In edit, when I pre populate the values in the form using setValue(), it does not set the second dropdown(state select in the sandbox below) values on the UI but it shows that it has set the value to the field(see in the console for field state).
[CodeSandBox] https://codesandbox.io/s/angry-murdock-h0lbsp?file=/src/App.js
Steps to reproduce:
Open this sandbox in the browser.
Click on the SET ALL VALUES button.
See the blank value in states select
Also, Whats the best way to populate a form like this, i.e. in defaultsValues or useEffect?
What am I missing here, so putting it for the experts here.
Thanks for your time.
The problem you are having is about setValue. This function does not trigger a re-render in most cases. You can use reset instead.
https://react-hook-form.com/api/useform/reset
Also, if you'd like to fill the form without any user interaction, use reset in useEffect with proper dependencies.
Lastly, If you'd like to have just them having initial values instead of being undefined, set defaultValues. It is also recommended in official documents:
Important: You should provide a proper default value and avoid undefined.
undefined is reserved for fallback from inline
defaultValue/defaultChecked to hook level defaultValues. undefined value is conflicting with controlled component as default state
https://react-hook-form.com/api/useform

Use form.getFieldValue to add logic between field without warning

I have a Ant Design 4.x.x Form element without multiple Form.Item. I need to implement some logic involving form items' values, for example disabling a field if another one's value equals something, or recalculate select options when a text input changes.
To do so, I create the form using Form.useForm() and use form.getFieldValue() in my functional component body and / or in the returned JSX, like so :
It is working as I expect to, but at startup, getFieldValue usages throw annoying
index.js:1 Warning: Instance created by `useForm` is not connect to any Form element. Forget to pass `form` prop?
I found that Form functions cannot be used before rendering, and the problem also occured when displaying a form in a Modal like stated in the docs.
So I feel that I'm missing something on how to correctly add custom logic between fields, or doing some calculation involving fields values in component body.
What would be a correct approach to do this ?
Try adding getContainer={false}, to your modal this will work for you.

cypress input field wont get cleared

I have a input field:
<input value="0">
which i can easily clear() and type("123") in cypress.
the value gets updated and everything is fine.
on the other side, a prefilled input field like below I cant update because cypress writes my value of .type("123") just at the beginning of the value.
<input value="1500000">
my method is the following:
.find("input")
.clear()
.type(`${input}{enter}`)
changes on the fields fire redux actions, we use redux for our whole state handling. could that be a problem?
otherwise, do you know of this issue?
Try adding an assertion to make Cypress 'wait' for the input to clear:
.clear().should('have.value', '')
.type(...)
I tested using the HTML found here and everything works fine (in the screenshot I wrote "Stefano" instead of the default value)
You hit the point when you cite React: this kind of state changes requires a bit more work to run as expected because React (and Vue etc.) obviously overwrites everything in the DOM.
You're facing a common issue where React re-renders the component as soon as an event is triggered... so you have to change the input value/defaultValue management in your React component, Google for it and you find a plethora of solutions about that 😊

Normalizing redux-form values set with initialValues

When I set my formvalues using initialValues, I want the normalization and async validation to run. I even tried dispatching both the blur and change action, but both don't work:
dispatch(blur('userdata', 'user_zipcode', '3021LC'));
dispatch(change('userdata', 'user_zipcode', '3021LC'));
What would be the right way to solve this problem?
As for normalizing, it's a little strange that you are initializing with non-normalized data. I would recommend reviewing the Value Lifecycle and perhaps using a combination of a parse and format functions.
As for running async validation, again it's odd that you might be initializing with invalid data, but there is a this.props.asyncValidate() function that you can call in your form component to trigger the async validation.
Does that help?
I'm having this same problem while using initialValues and not getting them normalized:
Using format instead of normalize seems to fix the problem but
format doesn't actually change the data you have on your store like the normalize does so, if you want to do that, then using both may be the best way to fix this? I'm not sure...
So, here's an example:
<Field component={MyCustomInputField} name="phone" format={normalizePhone} normalize={normalizePhone} label="Phone" type="tel" />
format is the first thing on the Value Lifecycle Hooks
Hope this helps!

Resources