javascript - 根据另一个字段值对一个字段使用 setFieldValue
问题描述
我正在使用 formik react 库并尝试根据另一个的 onChange 事件更新 2 个字段。例如,
price = quantity * totalPrice
price :
onChange={() => {setFieldValue('quantity',values.quantity? values.price / values.totalPrice:values.quantity, );
setFieldValue('totalPrice',values.totalPrice? values.price * values.quantity: values.totalPrice,);}}
quantity :
onChange={(value, e) => { this.disableFiled(value, e); setFieldValue('totalPrice',values.price ? values.price * values.totalPrice : ' ',);}}
totalPrice:
onChange={(value, e) => { this.disableFiled(value, e);setFieldValue('quantity',values.price ? values.totalPrice / price : ' ', ); }}
当数量有值时,总价将被禁用,反之亦然。但它不会正确计算其他字段
解决方案
我就是这样做的。
App.js 文件:
import React from "react";
import "./styles.css";
import { Formik } from "formik";
import * as Yup from "yup";
import CalculatedField from "./CalculatedField";
const App = () => (
<div className="app">
<Formik
initialValues={{ price: "", quantity: "", totalPrice: "" }}
onSubmit={async values => {
await new Promise(resolve => setTimeout(resolve, 500));
alert(JSON.stringify(values, null, 2));
}}
validationSchema={Yup.object().shape({
price: Yup.number("It's a number").required("Required"),
quantity: Yup.number("It's a number").required("Required"),
totalPrice: Yup.number("It's a number").required("Required")
})}
>
{props => {
const {
values,
touched,
errors,
isSubmitting,
handleChange,
handleBlur,
handleSubmit,
setFieldValue
} = props;
return (
<form onSubmit={handleSubmit}>
<div className="input-row">
<label htmlFor="quantity" style={{ display: "block" }}>
Quantity
</label>
<input
id="quantity"
name="quantity"
placeholder="Enter quantity"
type="number"
value={values.quantity}
onChange={handleChange}
onBlur={handleBlur}
className={
errors.quantity && touched.quantity
? "text-input error"
: "text-input"
}
/>
{errors.quantity && touched.quantity && (
<div className="input-feedback">{errors.quantity}</div>
)}
</div>
<div className="input-row">
<label htmlFor="price" style={{ display: "block" }}>
Price
</label>
<input
id="price"
name="price"
placeholder="Enter your price"
type="number"
value={values.price}
onChange={handleChange}
onBlur={handleBlur}
className={
errors.price && touched.price
? "text-input error"
: "text-input"
}
/>
{errors.price && touched.price && (
<div className="input-feedback">{errors.price}</div>
)}
</div>
<div className="input-row">
<label htmlFor="totalPrice" style={{ display: "block" }}>
Total Price
</label>
<CalculatedField
id="totalPrice"
type="number"
name="totalPrice"
value={values.totalPrice}
values={values}
setFieldValue={setFieldValue}
onChange={handleChange}
onBlur={handleBlur}
className={
errors.totalPrice && touched.totalPrice
? "text-input error"
: "text-input"
}
/>
{errors.totalPrice && touched.totalPrice && (
<div className="input-feedback">{errors.totalPrice}</div>
)}
</div>
<div className="input-row">
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</div>
</form>
);
}}
</Formik>
</div>
);
export default App;
计算字段.js
import React, { useEffect } from "react";
const CalculatedField = props => {
useEffect(() => {
var val = 0;
if (props.values.price && props.values.quantity) {
val = props.values.price * props.values.quantity;
}
props.setFieldValue("totalPrice", val);
}, [props.values]);
return (
<input
id="totalPrice"
type="number"
name="totalPrice"
value={props.values.totalPrice}
/>
);
};
export default CalculatedField;
这基本上是通过在 CalculatedField 组件的 useEffect 挂钩中调用 setFieldValue 方法来实现的。请记住 useEffect 将监视值的变化并在它们被修改时运行 setFieldValue 方法。
请关注 CodeSandbox 演示。https://codesandbox.io/s/affectionate-mirzakhani-who30?file=/src/App.js
推荐阅读
- javascript - 在量角器中运行测试套件时出现问题(浏览器实例)
- html - 如何从此页脚中删除符号?
- php - SoapClient 调用浏览器和 php-cli 执行的区别
- pandas - Python日期比较在.exe应用程序中不起作用
- ios - 在后台线程上访问 UIView 的属性
- javascript - 快速滚动以更改样式
- c# - InvalidSignatureException 与 AWS Kinesis Video Stream C#
- xamarin.ios - 我可以使用 mtouch 来构建库吗?
- c - 将带有附加库的文件构建为一个文件
- html - 如何让不同的网页使用一个 CSS 文件?