反应功能组件的setState不应用更改

时间:2020-09-10 09:41:19

标签: reactjs setstate arrow-functions use-state

我有一个react函数组件,它返回一个简单形式。 我要做的就是清除提交时字段的先前错误,然后再次验证字段。 令人惊讶的是,setState的第一个调用没有应用更改,但其他调用工作正常。

这是整个代码:

import React from "react";
import { TextField, Button } from "@material-ui/core";

export default function EditPresonalInfo() {
  const [fields, setFields] = React.useState({
    username: "",
    usernameHelper: "",
    usernameError: false,
    name: "",
    nameHelper: "",
    nameError: false,
  });

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

    setFields({
      ...fields,
      usernameError: false,
      usernameHelper: "",
      nameError: false,
      nameHelper: "",
    });

    if (fields.username.length < 4) {
      setFields({
        ...fields,
        usernameHelper: "use at least 4 characters",
        usernameError: true,
      });
      return;
    }

    if (fields.name.length < 2) {
      setFields({
        ...fields,
        nameHelper: "use at least 2 characters",
        nameError: true,
      });
      return;
    }
  };

  const handleChange = (fieldName) => (event) => {
    setFields({
      ...fields,
      [fieldName]: event.target.value,
    });
  };

  return (
    <form onSubmit={submitForm}>
      <TextField
        label="username"
        onChange={handleChange("username")}
        error={fields.usernameError}
        value={fields.username}
        helperText={fields.usernameHelper}
      />
      <TextField
        label="name"
        onChange={handleChange("name")}
        error={fields.nameError}
        value={fields.name}
        helperText={fields.nameHelper}
      />
      <Button type="submit">submit</Button>
    </form>
  );
}

有人可以帮助我解决我所缺少的内容吗?

4 个答案:

答案 0 :(得分:3)

您不必为每个验证设置状态。对于这种情况,我认为最好首先根据验证结果创建新状态,然后再设置状态。

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

  const newFields = { ...fields };

  if (fields.username.length < 4) {
    newFields["usernameHelper"] = "use at least 4 characters";
    newFields["usernameError"] = true;
  } else {
    newFields["usernameHelper"] = "";
    newFields["usernameError"] = false;
  }

  if (fields.name.length < 2) {
    newFields["nameHelper"] = "use at least 2 characters";
    newFields["nameError"] = true;
  } else {
    newFields["nameHelper"] = "";
    newFields["nameError"] = false;
  }

  setFields(newFields);
};

Edit practical-pine-rkho0

答案 1 :(得分:1)

这对我有用

 const submitForm = (e) => {
    e.preventDefault();
    let usernameHelper = "";
    let usernameError = false;
    let nameError = false;
    let nameHelper = "";

    if (fields.username.length < 4) {
      usernameHelper = "use at least 4 characters";
      usernameError = true;
    }
    if (fields.name.length < 2) {
      nameHelper = "use at least 2 characters";
      nameError = true;
    }
    setFields({
      ...fields,
      usernameError: usernameError,
      usernameHelper: usernameHelper,
      nameError: nameError,
      nameHelper: nameHelper,
    });
  };

答案 2 :(得分:0)

据此我了解到您想对表单进行验证,因此您已经在使用MaterialUI,建议您点击此链接https://react-hook-form.com/get-started#Applyvalidation。您将在那里找到最佳实践和更容易的实现。

答案 3 :(得分:0)

此刻,我误用了setFields来更改fields, 相反,可以像这样明确地完成

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

    fields.nameError= false
    fields.usernameError= false
    fields.nameHelper= ""
    fields.usernameHelper= ""

    if (fields.name.length < 2) {
      fields.nameHelper = "use at least 2 characters";
      fields.nameError = true;
    }

    if (fields.username.length < 4) {
      fields.usernameHelper = "use at least 4 characters";
      fields.usernameError = true;
    }

    setFields({
      ...fields
    })
  };