Formik Resetting the Initial Values using Yup validation with it - reactjs

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

Related

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

material-ui: Autocomplete with value and inputValue stored together

Goal:
It's about the Material Autocomplete from material-ui for React in variant freeSolo. I understand that one is asked to handle value and inputValue independently, but because Formik and Yup are used to save the state and apply validation I would prefer to have only one value outside. For splitting this increases complexity in the outer code noticeably.
Attempt:
https://codesandbox.io/s/autocomplete-with-a-single-state-v442c?file=/demo.tsx
Is an example where I set the prop inputValue to value.title || '' and in onInputChange I check if the inputValue matches an existing option and otherwise create a new object, both to mimic onChange.
Issue:
Unfortunately, the list does not become filtered anymore. I had added some logging in my attempt was everything worked as expected and I can't infer what issue the component runs into. I hope anyone has some idea or ideally working code? So again, my overall goal is to have only one value representing the state and that, therefore, needs to be an object.
So I realised this can not be done because the states value and inputValue update at different times. value is only affected by inputValue once the user clears the input completely, setting inputValue to '' and value becoming null. So the asynchronous nature does not allow storing it in a single value in a clean way.

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.

Formik - Update initial values after API call

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 !

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 😊

Resources