Formik returns 旧值状态

Formik returns old values state

我在使用 Formik 进行异步状态管理时遇到了这个问题。我需要根据输入的变化动态显示结果,但我每次都得到旧状态。你知道解决方法吗? 我需要 result 状态随着 Field 组件的变化而更新。

这是我的代码:

 function Simulator() {
  const [result, setResult] = useState(undefined);

  const LeasingSchema = Yup.object().shape({
    monthDuration: Yup.number()
      .min(6, "6 months minimum")
      .max(48, "48 months maximum")
      .required("Required"),
    amountFinanced: Yup.number()
      .min(10000, "The minimum finance is 10.000€")
      .max(100000, "The maximum finance is 100.000€")
      .required("Required")
  });

  const handleCalculation = (values, errors) => {
    const { monthDuration, amountFinanced } = values;

    if (monthDuration && amountFinanced && Object.keys(errors).length === 0) {
      //Round number
      const roundedValue = parseFloat(amountFinanced / monthDuration).toFixed(
        2
      );
      return setResult(roundedValue);
    } else {
      return setResult(undefined);
    }
  };

  return (
    <div className={styles.leasing}>
      <h1>Leasing simulator:</h1>

      <Formik
        initialValues={{
          monthDuration: "",
          amountFinanced: ""
        }}
        validationSchema={LeasingSchema}
        onSubmit={(values) => console.log(values)}
      >
        {({ errors, touched, values, handleChange }) => (
          <Form>
            <label htmlFor="form-monthly-duration">Monthly duration:</label>
            <Field
              type="number"
              name="monthDuration"
              placeholder="Months"
              id="form-monthly-duration"
              onChange={(e) => {
                handleChange(e);
                handleCalculation(values, errors);
              }}
            />
            {result && (
              <>
                <label htmlFor="result">Monthly fee:</label>
                <p>{result}</p>
              </>
            )}
            <button type="submit">Submit</button>
          </Form>
        )}
      </Formik>
    </div>
  );
}

export default Simulator;

handleCalculation 中的值永远不会更新,因为您使用的是 controlled component。表格数据必须按状态更新。

  1. 要按州更新,请将您的 result 设置为
const [result, setResult] = useState({
    monthDuration: 0,
    amountFinanced: <any number between 10000 to 100000>,
});
  1. 然后将Formik组件中的initialValues设置为
initialValues={result}

完整代码在这里:

const Simulator = () => {
    const [result, setResult] = useState({
        monthDuration: 0,
        amountFinanced: 10000,
    });

    const LeasingSchema = Yup.object().shape({
        monthDuration: Yup.number()
            .min(6, "6 months minimum")
            .max(48, "48 months maximum")
            .required("Required"),
        amountFinanced: Yup.number()
            .min(10000, "The minimum finance is 10.000€")
            .max(100000, "The maximum finance is 100.000€")
            .required("Required")
    });

    const handleCalculation = (values, errors) => {
        const { monthDuration, amountFinanced } = values;

        if (monthDuration && amountFinanced && Object.keys(errors).length === 0) {
            setResult({
                monthDuration: monthDuration,
                amountFinanced: amountFinanced,
            });
        }
    };

    return (
        <div>
            <h1>Leasing simulator:</h1>

            <Formik
                initialValues={result}
                validationSchema={LeasingSchema}
                onSubmit={(values) => console.log(values)}
            >
                {({ errors, values, handleChange, handleSubmit }) => (
                    <Form onSubmit={handleSubmit}>
                        <label htmlFor="form-monthly-duration">Monthly duration:</label>
                        <Field
                            type="number"
                            name="monthDuration"
                            placeholder="Months"
                            id="form-monthly-duration"
                            onChange={(e) => {
                                handleChange(e);
                                handleCalculation(values, errors);
                            }}
                        />
                        {(result.monthDuration || result.amountFinanced) && (
                            <>
                                <label htmlFor="result">Monthly fee:</label>
                                <p>{(values.amountFinanced / values.monthDuration).toFixed(2)}</p>
                            </>
                        )}
                        <button type="submit">Submit</button>
                    </Form>
                )}
            </Formik>
        </div>
    );
};

export default Simulator;

您也可以在设置状态时删除 return,因为它是不必要的。您可以在 React 生命周期中找到更多信息 docs.