form
form copied to clipboard
Uncontrolled to controlled input
Hi!
We're using react-form and it's great, but I have a question about a warning that keeps popping.
When not defining defaultValues
I get a warning from react saying that an input was changed from uncontrolled to controlled:
Warning: A component is changing an uncontrolled input of type undefined to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://fb.me/react-controlled-components
So I've been setting defaultValues
like this, which gets rid of the warning:
const { Form } = useForm({
defaultValues: React.useMemo(
() => ({
email: '',
password: '',
}),
[]),
onSubmit: async values => {
handleSubmit(values)
},
})
Now I have a use case where I need to create inputs dynamically, and while I can compute the values I feel like the form should be usable without defining defaultValues
.
This warning is also appears in the basic example from the docs: https://codesandbox.io/s/react-form-demo-wrybd
I guess this happens when react-forms input initializes on an input-field and makes it a controlled one, but I havent been able to wrap my head around it. I would love to hear your thoughts on this!
I'm having the same issue :(
@davidohlin you can define the defaultProps
to your component to get rid of this error:
import React from 'react';
import PropTypes from 'prop-types';
export const TextInput = props => <input type="text" {...props} />;
TextInput.defaultProps = {
value: ''
};
TextInput.propTypes = {
value: PropTypes.string
};
@billwatson017 Cool, I'll try that. I tested it quickly on the basic example from the docs and it seems to work.
@tannerlinsley do you think you can change the default behavior of a field value as controlled? Setting the defaultProps
or using the defaultValue
prop seems like a workaround.
import React from "react";
import ReactDOM from "react-dom";
import { useForm, useField, splitFormProps } from "react-form";
const InputField = React.forwardRef((props, ref) => {
const [field, fieldOptions, rest] = splitFormProps(props);
const {
meta: { error, isTouched, isValidating, message },
getInputProps
} = useField(field, fieldOptions);
return (
<>
<input {...getInputProps({ ref, ...rest })} />
</>
);
});
function App() {
const {
Form,
meta: { isSubmitting, isSubmitted, canSubmit, error }
} = useForm({
debugForm: true
});
return (
<Form>
<div>
<label>
Name: <InputField field="name" />
</label>
</div>
</Form>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);