can't concerve react material-ui autoCompletion value with formik - reactjs

I hope you're all well, I'm here with this message to express a concern, a problem that I've encountered. I use autoCompletion from materiall-ui combined with formik in reactjs.
I have trouble filling the autoCompletion field in edit mode, I can't display the exact value in my form so I lose the value of my autoCompletion when I switch from one step to another.

You will have to use initialValue to set value in Autocomplete, formik + materail ui has data binding issues so you can use https://stackworx.github.io/formik-mui/ sample example here https://codesandbox.io/s/formik-material-ui-autocomplete-rishd?file=/index.js:157-169
PS: Please reload sandbox in case of any dependencies error

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

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 !

React storybook showing formik form with errors

What is the simplest way to force a formik form to show fields in error?
I would like to this for a react storybook to show what our form looks like when a field has an error in it.
Each field in my form will only display an error if it has been touched and its value is not valid.
I can set the initial value of the fields but I can't figure out how to mark then all as touched so that the errors are displayed.
The Formik test for ErrorMessage might be of some use.
Note the use of setFieldError and setError
I managed this by setting initialErrors and initialTouched for the fields I wanted to display the error state for, in addition to setting initialValues.
In the Formik docs:
https://formik.org/docs/api/formik#initialerrors-formikerrorsvalues
https://formik.org/docs/api/formik#initialtouched-formiktouchedvalues
eg.
<Formik initialValues={} initialErrors={} initialTouched={}>...</Formik>
This worked in stories using both a decorator Formik component wrapper as well as the storybook-formik addon.

React client side validation with material-ui component

Some material-ui components have errorText as a prop which we can use to show errors, But, doing that in react become lot complex if my form has large number of field components.
Please suggest the best way to handle client-side validation with material-ui comonents.
I think your issue is that you have to manage a lot with state/store. In react validation is complex because of one-way binding.
This library https://github.com/vishalvisd/react-validator is one which I found that supports material-ui component validation. Though in general you may use this to validate any component.
I would suggest using some HoC (Higher-order Component) approach. I tested many solutions for form validation in React JS, the one that I always choose is: react-validation-mixin. Take a look at this example.
Example of the standard input:
<input
type='text'
placeholder='Username'
value={this.props.username}
onChange={this.onChange('username')}
onBlur={this.props.handleValidation('username')}
/>
In this example value of that input comes from props (example with Flux implementation) and that's probably what you aim for too (lots of inputs).
onChange will need to handle value change so that this.props.username gets updated too and onBlur will trigger validation check (so that the error will show up once user leaves the input).
In order to get the error message, use: this.props.getValidationMessages('username')
It's a universal solution and you can use it in different libs. But taking TextField from material-ui, as you asked:
<TextField
floatingLabelText="Username"
value={this.props.username}
errorText={this.props.getValidationMessages('username')}
onChange={this.onChange('username')}
onBlur={this.props.handleValidation('username')}
...
/>
Remember to use HoC with your component: export default validation(strategy)(UserLogin) That way, you will get all the necessary helper methods in props.
If you are using Redux in React project, redux-form give you a simple way to implement form validation.
Check this out: http://redux-form.com/6.4.3/examples/syncValidation/

Input field and React where Input field is not editable because of react id in attr

I have a specific need to only make one input field in a form (legacy code) a react component. So, I wrap the input with a div and render into it the 'new' input field that needs some special behavior.
The problem arises because the input field is no longer editable. I try to type into it.. nothing. I narrowed it down to the following:
<input type="text" **data-reactid=".2.0.0.0.1.0.0.1.2.0"**
When I remove that "data-reactid....", by editing via console, it works.
So when I am using react to sub out one form input field with a react one, it doesn't work unless I manually remove that data-reactid..
Is there a workaround for this, or a reason why this is happening?
Well its just a data attribute written by react to help them render into the DOM more efficiently so it should have no real impact on a input element or any element (unless there is code or style explicitly disabling the input) - I realize that this is no real help - because it happens to you, but this is not typical of react apps with inputs or element with data-attributes.
But if its the only bit of react on the page then that id is a bit long and I would have expected something like ".0" or ".0.0" if its wrapped in a div that react controls.
The react-id is only used by the React engine to work out what elements of the DOM need to be re-written when there are changes to state or props in your components.
One thing I noticed is, typically there would be an ID or in react a ref that you applied to the input in order to interact with it (such as getting its value).
I include the mark-up from a simple entry box on the user login form of a working app, as you can see it's not significantly different from what you have and works on all browsers Windows and Mac down to IE8 included.. (but not any IE below 8) and you need various shims for getting it work on IE8.
<input class="username-text-field" id="user-id" type="text" data-reactid=".0.0.0.1.3.0.0.2">
If none of these apply or you have them covered then practicably here should be no reason why your input should be disabled. It should just act like any other input. Have tried just dropping you component onto a simple HTML page with only the input on it, just to debug through the component in isolation?
That said,
It does feel that loading the entire React engine and wiring up a component to allow a single input field is a little over-kill. I realize that you're trying not to have to recreate exactly the same functionality you already have in react again on the legacy form, but if your render function is not too onerous then maybe a simple bit of JavaScript or JQuery might be the answer as a one off in the legacy solution (rather than the hit for the library) - just a thought

Resources