Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Mobx Warning: A component is changing an uncontrolled input

I use React + TypeScript + Mobx. I made the form with input, everything is working, but the browser gives an error. What am I doing wrong?

Warning: A component is changing an uncontrolled input of type text 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.

Form:

@observer
export class SearchForm extends React.Component {

    @observable
    private _inputText: string;

    submitForm = (event: SyntheticEvent<HTMLFormElement>) => {
    event.preventDefault();
    }

    render() {
      return (
        <form onSubmit={this.submitForm}>
          <InputField
            value={this._inputText}
            onChange={action((value: string) => this._inputText = value)}
          />
       </form>
    );}}

Input:

interface Props {
  value: string;
  onChange: (inputText: string) => void;
}

@observer
export class InputField extends React.Component<Props> {

  onChange = (event: SyntheticEvent<HTMLInputElement>) => {
  this.props.onChange(event.currentTarget.value);
  }

  render() {
    return (
      <div>
        <input
          type="text"
          value={this.props.value}
          onChange={this.onChange}
        />
     </div>
   );
 }
}
like image 928
cooperJCW Avatar asked Jun 06 '18 08:06

cooperJCW


People also ask

How do you fix a component is changing an uncontrolled input to be controlled?

The warning "A component is changing an uncontrolled input to be controlled" occurs when an input value is initialized to undefined but is later changed to a different value. To fix the warning, initialize the input value to an empty string, e.g. value={message || ''} .

Which should not happen decide between using a controlled or uncontrolled input element for the lifetime of the component?

This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. In this tutorial, we will learn why this warning occurs and how to solve it.

What is control and Uncontrol component in react?

In a controlled component, form data is handled by a React component. The alternative is uncontrolled components, where form data is handled by the DOM itself. To write an uncontrolled component, instead of writing an event handler for every state update, you can use a ref to get form values from the DOM.


1 Answers

React's inputs are controlled/uncontrolled based on the presence of the value prop on the input. You're passing the value prop, but _inputText starts as undefined. And when input's value starts undefined, React will always start the input in uncontrolled mode.

Once you type in the input, _inputText is no longer undefined, and the input flips to controlled mode, and you get the warning.

For your case, the fix is simple; just initialize _inputText to the empty string:

@observable
private _inputText: string = '';

You could also tweak your <InputField /> to force undefined value props to be the empty string:

  render() {
    return (
      <div>
        <input
          type="text"
          value={this.props.value == null ? '' : this.props.value}
          onChange={this.onChange}
        />
     </div>
   );
 }
like image 154
adharris Avatar answered Sep 30 '22 16:09

adharris