简体   繁体   中英

Warning: A component is changing a controlled input of type text to be uncontrolled. (React.js)

I have the following component where I display user's existing details in the inputs as values and user should be able to change those details and click save. But the issue is that it shows the following error in the console:

  **index.js:1 Warning: A component is changing a controlled input of type text to be uncontrolled.**

Here is the component code:

const Settings = (props) => {
  const { createUser, isAuthenticated, history, errors } = props;
  const dispatch = useDispatch();
  const authUser = useSelector(state => state.auth.user);

  const [user, setUser] = useState({
    data: {
      name: "",
      email: "",
      password: "",
    },
  });

  const [error, setError] = useState({
    nameError: "",
    emailError: "",
    passwordError: "",
  });

  useEffect(() => {
    setUser({
      data: {
        email:authUser.email,
      }
    });    
  }, [authUser]);


  const { name, email, password } = user.data;
  const { nameError, emailError, passwordError } = error;

  const onUpdateUser = (e) => {
    e.preventDefault();

    const isValid = formValidator(user.data, setError);

    if (isValid) {
      dispatch(updateUser(user.data))
    }
  };

  const onChange = (e) => {
    const { name, value } = e.target;
    const { data } = user;
    setUser({
      data: {
        ...data,
        [name]: value,
      },
    });
  };

  return (
    <BForm title="Create an account" handleSubmit={onUpdateUser}>
      {errors ? <p className="error-feedback">{errors}</p> : ""}
      <BInput
        name="name"
        type="text"
        handleChange={onChange}
        value={name}
        placeholder="Your Name"
        error={nameError}
        
      />
      <BInput
        name="email"
        type="email"
        handleChange={onChange}
        value={email}
        placeholder="Email"
        error={emailError}
        required
      />
      <BInput
        name="password"
        type="password"
        value={password}
        handleChange={onChange}
        placeholder="Password"
        error={passwordError}
        required
      />
      <div className="buttons">
        <BButton customClass="login-btn" isfullwidth={true} type="submit">
          {" "}
          Save{" "}
        </BButton>
      </div>
    </BForm>
  );
};

export default Settings;

What is wrong and how can be it fixed? I need to let see the existing values and then change whatever they want.

useState doesn't allow patching like setState did (even if it did, your data is nested at the data key so it still wouldn't work). The problem is at this line:

  useEffect(() => {
    setUser({
      data: {
        email:authUser.email,
      }
    });    
  }, [authUser]);

It needs to look like this:

  useEffect(() => {
    setUser(({data}) => ({
     data: {
      ...data,
      email:authUser.email
    }
   }))
  }, [authUser]);

Otherwise, it will remove the name and password keys and then the inputs will have undefined values (eg become uncontrolled).

You problem in useEffect . Because you only update email so name and password will be lost. So the initial value of these input will show this warning. You can update like this:

  useEffect(() => {
    setUser(preState => ({
      data: {
        ...preState.data,
        email:authUser.email,
      }
    }));    
  }, [authUser]);

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