无法通过 React 和 Redux 将相同的表单组件用于添加或编辑模式

Posted

技术标签:

【中文标题】无法通过 React 和 Redux 将相同的表单组件用于添加或编辑模式【英文标题】:Unable to use the same form component for Add or Edit Mode with React & Redux 【发布时间】:2021-09-25 18:58:20 【问题描述】:

我无法在添加和编辑模式下使用相同的表单组件。我能够在编辑模式下填充表单组件上的值,但无法在输入字段中输入具有现有值的内容。每当我们有 id 时,我都会触发 redux 操作,以便他可以获得单个联系人详细信息,并且从 reducer 我提取联系人状态并检查每个输入字段,如果它处于编辑模式,则显示来自 reducer我们有喜欢的contact.name,contact.email之类的。通过这种方法,我能够在每个输入字段上填充现有值,但无法输入内容 你能看看下面的代码这种方法有什么问题吗?

const AddContact = () => 
  const classes = useStyles();
  const  contact  = useSelector((state) => state.data);
  const [state, setState] = useState(
    name: contact.name || "",
    mobile: contact.mobile || "",
    email: contact.email || "",
    address: contact.address || "",
  );
  const [editMode, setEditMode] = useState(false);
  const [error, setError] = useState("");

  let history = useHistory();
  let dispatch = useDispatch();
  const  name, email, mobile, address  = state;

  const handleInputChange = (e) => 
    let  name, value  = e.target;
    setState( ...state, [name]: value );
  ;

  const  id  = useParams();

  useEffect(() => 
    setState(contact);
  , [editMode]);

  useEffect(() => 
    if (id) 
      setEditMode(true);
      dispatch(getContactStart(id));
    
  , [id]);

  console.log("id", id);

  const handleSubmit = (e) => 
    e.preventDefault();
    if (!name || !address || !email || !mobile) 
      setError("Please input all input Field");
     else 
      dispatch(addContactStart(state));
      // setTimeout(() => history.push("/"), 1500);
      history.push("/");
      setError("");
    
  ;
  return (
    <div>
      <Button
        style= width: "100px", marginTop: "20px" 
        variant="contained"
        color="secondary"
        onClick=() => history.push("/")
      >
        Go Back
      </Button>
      <h2>!editMode ? "Add User" : "Edit User"</h2>
      error && <h3 style= color: "red" >error</h3>
      <form
        className=classes.root
        noValidate
        autoComplete="off"
        onSubmit=handleSubmit
      >
        <TextField
          id="standard-basic"
          label="Name"
          value=editMode ? contact.name : name
          name="name"
          type="text"
          onChange=handleInputChange
        />
        <br />
        <TextField
          id="standard-basic"
          label="Email"
          name="email"
          value=editMode ? contact.email : email
          type="email"
          onChange=handleInputChange
        />
        <br />
        <TextField
          id="standard-basic"
          label="Contact"
          value=editMode ? contact.mobile : mobile
          name="mobile"
          type="number"
          onChange=handleInputChange
        />
        <br />
        <TextField
          id="standard-basic"
          label="Address"
          value=editMode ? contact.address : address
          name="address"
          type="text"
          onChange=handleInputChange
        />
        <br />
        <Button
          style= width: "100px" 
          variant="contained"
          color="primary"
          type="submit"
          onChange=handleInputChange
        >
          Submit
        </Button>
      </form>
    </div>
  );
;

export default AddContact;

【问题讨论】:

【参考方案1】:

在每个输入字段中添加defaultValue 而不是value,试试下面的代码:

const AddContact = () => 
  const classes = useStyles();
  const  contact  = useSelector((state) => state.data);
  const [state, setState] = useState(
    name: contact.name || "",
    mobile: contact.mobile || "",
    email: contact.email || "",
    address: contact.address || "",
  );
  const [editMode, setEditMode] = useState(false);
  const [error, setError] = useState("");

  let history = useHistory();
  let dispatch = useDispatch();
  const  name, email, mobile, address  = state;

  const handleInputChange = (e) => 
    let  name, value  = e.target;
    setState( ...state, [name]: value );
  ;

  const  id  = useParams();

  useEffect(() => 
    setState(contact);
  , [editMode]);

  useEffect(() => 
    if (id) 
      setEditMode(true);
      dispatch(getContactStart(id));
    
  , [id]);

  console.log("id", id);

  const handleSubmit = (e) => 
    e.preventDefault();
    if (!name || !address || !email || !mobile) 
      setError("Please input all input Field");
     else 
      dispatch(addContactStart(state));
      // setTimeout(() => history.push("/"), 1500);
      history.push("/");
      setError("");
    
  ;
  return (
    <div>
      <Button
        style= width: "100px", marginTop: "20px" 
        variant="contained"
        color="secondary"
        onClick=() => history.push("/")
      >
        Go Back
      </Button>
      <h2>!editMode ? "Add User" : "Edit User"</h2>
      error && <h3 style= color: "red" >error</h3>
      <form
        className=classes.root
        noValidate
        autoComplete="off"
        onSubmit=handleSubmit
      >
        <TextField
          id="standard-basic"
          label="Name"
          defaultValue=editMode ? contact.name : name
          name="name"
          type="text"
          onChange=handleInputChange
        />
        <br />
        <TextField
          id="standard-basic"
          label="Email"
          name="email"
          defaultValue=editMode ? contact.name : name
          type="email"
          onChange=handleInputChange
        />
        <br />
        <TextField
          id="standard-basic"
          label="Contact"
          defaultalue=editMode ? contact.mobile : mobile
          name="mobile"
          type="number"
          onChange=handleInputChange
        />
        <br />
        <TextField
          id="standard-basic"
          label="Address"
          defaultValue=editMode ? contact.address : address
          name="address"
          type="text"
          onChange=handleInputChange
        />
        <br />
        <Button
          style= width: "100px" 
          variant="contained"
          color="primary"
          type="submit"
          onChange=handleInputChange
        >
          Submit
        </Button>
      </form>
    </div>
  );
;

export default AddContact;

【讨论】:

以上是关于无法通过 React 和 Redux 将相同的表单组件用于添加或编辑模式的主要内容,如果未能解决你的问题,请参考以下文章

如何将 react-datepicker 与 redux 表单一起使用?

无法使用React redux读取未定义的地图属性

无法在 react-redux 中异步发布

在 react redux saga 中处理同步

React Redux表单提交未给出正确的结果

为什么React / Redux表单中的输入会将数字更改为字符串?