反应输入警告:组件正在将文本类型的受控输入更改为不受控制

时间:2020-04-23 03:25:43

标签: reactjs input warnings

我正在通过使用一个Fake API网站来练习REST API。对于前端,我使用React打字稿和React router dom进行路由。我通过使用Fake API的登录名成功登录了电子邮件和密码,并重定向到列出用户,在这里我从Fake API获取了数据并显示了用户名,图像。我使用了“编辑”按钮,单击该按钮后,它将重定向到我的“更新”组件,将在其中填充输入字段,然后更新数据。我的更新组件可以正常运行,但是在控制台中,我在输入字段后立即收到警告。这里是Error visualization

这是React Update组件

import React, { useState, useEffect } from "react";
import axios from "axios";

const Update = props => {
  const [state, setState] = useState({
    first_name: "",
    last_name: "",
    email: ""
  });

  const [loading, setLoading] = useState(false);
  useEffect(() => {
    axios
      .get("https://reqres.in/api/users/" + props.match.params.id)
      .then(response => {
        setState({
          first_name: response.data.data.first_name,
          last_name: response.data.data.last_name,
          email: response.data.data.email
        });
      })
      .catch(function(error) {
        console.log(error);
      });
  }, [props.match.params.id]);

  const onChangeFirstName = e => {
    setState({
      first_name: e.target.value
    });
  };

  const onChangeLastName = e => {
    setState({
      last_name: e.target.value
    });
  };
  const onChangeEmail = e => {
    setState({
      email: e.target.value
    });
  };

  const onSubmit = e => {
    e.preventDefault();
    setLoading(true);
    const obj = {
      first_name: state.first_name,
      last_name: state.last_name,
      email: state.email
    };
    axios
      .patch("https://reqres.in/api/users/" + props.match.params.id, obj)
      .then(res => console.log(res.data));
    setLoading(false);
    props.history.push("/users");
  };

  return (
    <div>
      <form onSubmit={onSubmit}>
        <div className="form-group">
          <label>First Name: </label>
          <input
            type="text"
            className="form-control"
            value={state.first_name}
            onChange={onChangeFirstName}
            id="first_name"
          />
        </div>

        <div className="form-group">
          <label>Last Name: </label>
          <input
            type="text"
            className="form-control"
            value={state.last_name}
            onChange={onChangeLastName}
            id="last_name"
          />
        </div>

        <div className="form-group">
          <label>Email: </label>
          <input
            type="email"
            className="form-control"
            value={state.email}
            onChange={onChangeEmail}
            id="email"
          />
        </div>
        <div className="form-group">
          <button
            className="btn waves-effect blue lighten-1"
            type="submit"
            name="action"
            disabled={loading}
          >
            {loading ? "loading..." : "save"}
          </button>
        </div>
      </form>
    </div>
  );
};

export default Update;

1 个答案:

答案 0 :(得分:0)

使用钩子,在set the state对象时,您需要自己合并所有属性。换句话说,如果您用state updater更新对象的属性,则对象的其余属性不会像类组件中的this.setState那样被自身合并。

将您的onChange修改为:

const onChangeFirstName = e => {
    const val = e.target.value;
    setState(prevState => ({
      ...prevState,
      first_name: val
    }));
  };

请参见working demo

也建议: 除了编写多个onChange之外,您还可以简化并仅使用一个。

赞!

<input
 type="text"
 className="form-control"
 value={state.first_name}
 onChange={onChange}
 id="first_name"
 name="first_name" />

...

const onChange = e => {
    const {name, value} = e.target;
    setState(prevState => ({
      ...prevState,
      [name]: value
    }));
  };