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。表格数据必须按状态更新。
- 要按州更新,请将您的
result
设置为
const [result, setResult] = useState({
monthDuration: 0,
amountFinanced: <any number between 10000 to 100000>,
});
- 然后将
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.
我在使用 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。表格数据必须按状态更新。
- 要按州更新,请将您的
result
设置为
const [result, setResult] = useState({
monthDuration: 0,
amountFinanced: <any number between 10000 to 100000>,
});
- 然后将
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.