简体   繁体   中英

Warning: A component is changing a controlled input to be uncontrolled input in react js

When my component is rendered a warning is showing in my console that is caused by the value changing from a defined to undefined value. I have set the value attribute in the form tag to their respective state but still getting the error. Please check the useEffect too.

import React, { useState, useEffect } from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import axios from "axios";

const CreateExercise = (props) => {
  const [userDetails, setUserDetails] = useState({
    //Fetching the initial state
    username: "",
    description: "",
    duration: 0,
    date: new Date(),
    users: [],
  });

  useEffect(() => {
    axios.get("http://localhost:5000/users/").then((res) => {
      //Fetching array of users
      if (res.data.length > 0) {
        console.log(res.data);
        setUserDetails({
          users: res.data.map((user) => user.username), //Updating user to its name
          username: res.data[0].username, //First content of array i.e.
        }); //username
      }
    });
  }, []);

  //Handling the change handler for the form input

  const changeUsernameHandler = (e) => {
    setUserDetails((prevState) => {
      return {
        ...prevState,
        username: e.target.value,
      };
    });
  };

  const changeDescriptionHandler = (e) => {
    setUserDetails((prevState) => {
      return {
        ...prevState,
        description: e.target.value,
      };
    });
  };

  const changeDurationHandler = (e) => {
    setUserDetails((prevState) => {
      return {
        ...prevState,
        duration: e.target.value,
      };
    });
  };

  const changeDateHandler = (date) => {
    setUserDetails((prevState) => {
      return {
        ...prevState,
        date: date,
      };
    });
  };
  //On submitting create exercise
  const onSubmitHandler = (e) => {
    e.preventDefault();
    const exercise = {
      username: userDetails.username,
      description: userDetails.description,
      duration: userDetails.duration,
      date: userDetails.date,
    };
    console.log(exercise);

    axios
      .post("http://localhost:5000/exercises/add", exercise) //updating the component
      .then((res) => console.log(res.data));

    window.location = "/"; //After submission redirect to the
    //path
  };

  return (
    //Form containing
    //username,Description,Duration and Dat
    <div>
      <h3>Create new Exercise log</h3>
      <form onSubmit={onSubmitHandler}>
        <div className="form-group">
          <label>Username: </label>
          <select
            required
            className="form-control"
            onChange={changeUsernameHandler}
            value={userDetails.username}
          >
            {userDetails.users.map((user) => {
              return (
                <option key={user} value={user}>
                  {user}
                </option>
              );
            })}
          </select>
        </div>
        <div className="form-group">
          <label>Description: </label>
          <input
            type="text"
            required
            className="form-control"
            onChange={changeDescriptionHandler}
            value={userDetails.description}
          />
        </div>
        <div className="form-group">
          <label>Duration (in minutes): </label>
          <input
            type="number"
            className="form-control"
            onChange={changeDurationHandler}
            value={userDetails.duration}
          />
        </div>
        <div className="form-group">
          <label>Date: </label>
          <div>
            <DatePicker onChange={changeDateHandler} selected={userDetails.date} />
          </div>
        </div>

        <div>
          <input type="submit" value="Create Exercise Log" className="btn btn-primary" />
        </div>
      </form>
    </div>
  );
};

export default CreateExercise;

what do I have to change in order to remove that above error?

setUserDetails({           
  users: res.data.map((user) => user.username), 
  username: res.data[0].username, 
}); 

in the above code, you didn't use the same approach you did as in the rest of events,

       setUserDetails((prevState) => {
          return {
            ...prevState,
            username: e.target.value,
          };
        });

basically prevState needs to be preserved,

  setUserDetails({
    ...userDetails,
    users: ...,
    username: ...

As for the reason you are getting this error, react doesn't like the idea that you randomly either attach the value or not. They refer it as either uncontrolled or controlled case. They are happy with one of the case, but just not random on the fly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM