1

At the moment I try to write in the form and save it in the state, I get this error:

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.

import React from 'react';

class ExerciseNew extends React.Component {

  constructor(props) {
    super(props);
    this.state = {value: ''}
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleSubmit = (e) => {
      e.preventDefault();
      console.log(this.state)
  }

  handleChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value
    })
  }

  render() {
    return (
      <div className="container">
        <form
          onSubmit={this.handleSubmit}
          >
          <div className="form-group">
            <input
              type="text"
              className="form-control"
              placeholder="title"
              name="title"
              onChange={this.handleChange}
              value={this.state.title}
             />
          </div>
          <div className="form-group">
            <input
              type="text"
              className="form-control"
              placeholder="description"
              name="description"
              onChange={this.handleChange}
              value={this.state.description}
             />
          </div>
          <div className="form-group">
            <input
              type="text"
              className="form-control"
              placeholder="img"
              name="img"
              onChange={this.handleChange}
              value={this.state.img}
             />
          </div>
          <div className="form-row">
            <div className="col">
              <input
                type="text"
                className="form-control"
                placeholder="leftColor"
                name="leftColor"
                onChange={this.handleChange}
                value={this.state.leftColor}
              />
            </div>
            <div className="col">
              <input
                type="text"
                className="form-control"
                placeholder="rightColor"
                name="rightColor"
                onChange={this.handleChange}
                value={this.state.rightColor}
              />
            </div>
          </div>
          <button
          type="submit"
          className="btn btn-primary"
          >
            Submit
          </button>
        </form>
      </div>
    )
  }
}

export default ExerciseNew;

I find it curious because I am following the documentation of react, along with this video in Spanish.

I tried using babeljs and the features of ES7 so as not to have to create the constructor, so I did something like this:

import React from 'react';

class ExerciseNew extends React.Component {

  state = {}

  handleSubmit = (e) => {
      e.preventDefault();
      console.log(this.state)
  }

  handleChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value
    })
  }

  render() {
    return (
      <div className="container">
        <form
          onSubmit={this.handleSubmit}
          >
          <div className="form-group">
            <input
              type="text"
              className="form-control"
              placeholder="title"
              name="title"
              onChange={this.handleChange}
              value={this.state.title}
             />
          </div>
          <div className="form-group">
            <input
              type="text"
              className="form-control"
              placeholder="description"
              name="description"
              onChange={this.handleChange}
              value={this.state.description}
             />
          </div>
          <div className="form-group">
            <input
              type="text"
              className="form-control"
              placeholder="img"
              name="img"
              onChange={this.handleChange}
              value={this.state.img}
             />
          </div>
          <div className="form-row">
            <div className="col">
              <input
                type="text"
                className="form-control"
                placeholder="leftColor"
                name="leftColor"
                onChange={this.handleChange}
                value={this.state.leftColor}
              />
            </div>
            <div className="col">
              <input
                type="text"
                className="form-control"
                placeholder="rightColor"
                name="rightColor"
                onChange={this.handleChange}
                value={this.state.rightColor}
              />
            </div>
          </div>
          <button
          type="submit"
          className="btn btn-primary"
          >
            Submit
          </button>
        </form>
      </div>
    )
  }
}

export default ExerciseNew;

and still I get the same error.

0

1 Answer 1

4

Your form is already a controlled components.

You are getting warning beacuse, you have not initialized your state. You need to have each variable in state like,

this.state = {
  title: '',
  description: '',
  img: '',
  leftColor: '',
  rightColor: ''
}

Note: A you are already using arrow function for handleSubmit & handleChange, you don't need to bind them in constructor,

this.handleChange = this.handleChange.bind(this);  //not needed
this.handleSubmit = this.handleSubmit.bind(this);  //not needed

Live Example:

class ExerciseNew extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      title: "",
      description: "",
      img: "",
      leftColor: "",
      rightColor: "",
    };
  }

  handleSubmit = (e) => {
      e.preventDefault();
      console.log(this.state)
  }

  handleChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value
    })
  }

  render() {
    return (
      <div className="container">
        <form
          onSubmit={this.handleSubmit}
          >
          <div className="form-group">
            <input
              type="text"
              className="form-control"
              placeholder="title"
              name="title"
              onChange={this.handleChange}
              value={this.state.title}
             />
          </div>
          <div className="form-group">
            <input
              type="text"
              className="form-control"
              placeholder="description"
              name="description"
              onChange={this.handleChange}
              value={this.state.description}
             />
          </div>
          <div className="form-group">
            <input
              type="text"
              className="form-control"
              placeholder="img"
              name="img"
              onChange={this.handleChange}
              value={this.state.img}
             />
          </div>
          <div className="form-row">
            <div className="col">
              <input
                type="text"
                className="form-control"
                placeholder="leftColor"
                name="leftColor"
                onChange={this.handleChange}
                value={this.state.leftColor}
              />
            </div>
            <div className="col">
              <input
                type="text"
                className="form-control"
                placeholder="rightColor"
                name="rightColor"
                onChange={this.handleChange}
                value={this.state.rightColor}
              />
            </div>
          </div>
          <button
          type="submit"
          className="btn btn-primary"
          >
            Submit
          </button>
        </form>
      </div>
    )
  }
}

ReactDOM.render(
  <ExerciseNew/>,
  document.getElementById("root")
);
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.development.js"></script>

Sign up to request clarification or add additional context in comments.

1 Comment

just to highlight: thing happens because value={this.state.title} is undefined initially. And to React it's the same if there was no value prop at all. So component is supposed to be uncontrollable... but later becomes controllable. That's how initializing state with empty string, as suggests @ravibagul91 helps

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.