I Love ReactJS

Controlled and uncontrolled components

controlled and uncontrolled components

React the concept of controlled and uncontrolled components is relative to the form. In React , the form element usually holds the internal state , so it works differently from other HTML elements. The different implementation of state within the form element results in controlled and uncontrolled components.

controlled components

in the HTML form elements, they usually maintain a set of state and update UI as the user inputs. This behavior is not controlled by our program. If we establish a dependency between the state attribute and the value of the form element in React , then update the state attribute through the onChange event and setState () . You can control what happens to the form during user input. React form input elements that control values in this way are called controlled components. & nbsp;

if a input input box is defined in React , it does not have the same bi-directional binding function as v-model in Vue , that is to say, we do not have an instruction to combine the data with the input box, and the user enters the content in the input box, and then the data is updated synchronously.


class Input extends React.Component {

  render () {

    return <input name="username" />

  }

}

when users enter content in the input box on the interface, it maintains a state . This state is not the this.state that we usually see, but the abstract state on each form element, so that we can update the UI according to the user's input. If we want to control the content of the input box, the content of the input box depends on the value attribute in input . Then we can define an attribute named username in this.state , and specify value on input as this attribute.


class Input extends React.Component {

  constructor (props) {

    super(props);

    this.state = { username: "1" };

  }

  render () {

    return <input name="username" value={this.state.username} />

  }

}

but at this time you will find that the content of input is read-only, because value will be controlled by our this.state.username , and this.state.username will not be updated automatically when users enter new content, so the content in input will not change, and the console will usually throw a Warning .


Warning: You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.

you have provided a value property for the form field without a onChange handler, which will render the read-only field. If the field should be mutable, use defaultValue , otherwise set onChange or readOnly . & nbsp;

this Warning actually gives a solution to this problem. We only need to listen to the component's onChange event to listen for changes in input and use setState to update this.state.username , so that we can control the value of this form element in the current component, which is the controlled component.


class Input extends React.Component {

  constructor (props) {

    super(props);

    this.state = { username: "1" };

  }

  render () {

    return (

      <>

        <input name="username" value={this.state.username}

          onChange={e => this.setState({username: e.target.value})}

        />

        <button onClick={() => console.log(this.state.username)} >Log</button>

      </>

    )

  }

}

In addition, it should be noted that there are drawbacks if this component is called as a common component. Although the Input component itself is a controlled component, the opposite caller loses control over changing the value of the Input component, so for the caller, the Input component is an uncontrolled component, and invoking the controlled component in the way uncontrolled components are used is an antipattern. The following examples belong to Hooks .


// component provider

function Input({ defaultValue }) {

  const [value, setValue] = React.useState(defaultValue)

  return <input value={value} onChange={e => setValue(e.target.value)} />

}

  


// caller

function UseInput() {

  return <Input defaultValue={1} />

}

if you want Input components to be controlled for both the provider and the caller, you only need the provider to relinquish control.


// component provider

function Input({ value, onChange }) {

  return <input value={value} onChange={onChange} />

}

  


// caller

function UseInput() {

  const [value, setValue] = React.useState(1);

  return <Input value={value} onChange={e => setValue(e.target.value)} />

}

uncontrolled components

if the form element does not go through state , but is modified by ref or directly manipulated DOM , then its data cannot be controlled through state , which is an uncontrolled component.


class Input extends React.Component {

  constructor (props) {

    super(props);

    this.input = React.createRef();

  }

  render () {

    return (

      <>

        <input name="username" ref={this.input} />

        <button onClick={() => console.log(this.input.current.value)} >Log</button>

      </>

    )

  }

}

Summary

controlled components

& nbsp; & nbsp; * by setting the default value of the form in the initial state .

& nbsp; & nbsp; * calls the onChange event handler whenever the value of the form changes.

The

& nbsp; & nbsp; * event handler gets the changed state through the composite object event , and updates the state of the application.

& nbsp; & nbsp; * SetState triggers the re-rendering of the view and completes the update of the form component values.

uncontrolled components

Exit mobile version