货币输入不将 0 视为小数点后的其他数字
Input for currency not treating 0 like other numbers after decimal
我正在制作一个反应应用程序,它接受一个应该显示到小数点后两位的输入。当默认输入在小数点后有一个数字时,它应该在其后添加一个带有 0 的第二个数字。它还允许我添加无限数量的“0”,但将任何其他数字限制在小数点后 2 位。
图中有两个不同的问题:
案例一。
这是首次加载时输入的外观。首选显示为 1.60(两位小数)
案例二。
当前行为允许用户添加无限个 0(它限制在小数点后 2 位的任何其他数字)。预期行为应限制所有数字,包括小数点后 2 位的 0。
function ProductMaterial() {
const [name, setName] = useState("");
function handleChange(e) {
let val = e.target.value;
if (val.includes(".") && val.split(".")[1].length > 2) {
}
else {
setName(parseFloat(val));
setMaterialState(parseFloat(val));
}
}
return (
<div className="input-group-sm col-xs-2 material input-group">
<div className="input-group-prepend">
<span className="input-group-text">$</span>
</div>
<input
className="form-control"
type="number"
min="0.00"
onChange={handleChange}
value={product.material}
/>
</div>
);
}
这里是setMaterialState的代码。它更改 product.material 值,然后在 useEffect()
函数中调用 setMaterial()
。 setMaterial()
获取产品的 ID 和新的 material 值并将其保存到状态。
function setMaterialState(newMaterial) {
product.material = newMaterial;
}
useEffect(() => {
setMaterial(product.id, product.material);
}, [product.material]);
我知道这里的问题是在第一次加载时没有任何东西触发 onChange()
函数。我试过将 value={product.material}
设置为 value={product.material.toFixed(2)}
,但这使得修复输入变得困难。有没有什么好的方法可以在之前初始化它,也许使用 UseEffect()
语句?除此之外,我不确定为什么可以无限期地添加 0。
更新:
使用 Photonic 建议的 onKeyPress=
答案解决了前导 0 的第一个问题。
但是,我仍在努力解决当末尾为 0 时强制它保留两位小数的问题。我意识到不开始执行 1.60 的问题是由于它被转换为浮点值而不是字符串。我尝试做一个 UseEffect() [] 并用 product.material.toFixed(); 强制它转到小数点后 2 位;以及修改数据以 1.60 开头,但似乎强制保留两位小数的唯一方法是将其保留为字符串或使用 product.material.toFixed(2)
将其转换为字符串。输入 value={product.material}
中的值需要是一个数字才能正确执行计算并收集用户输入。我不确定最好的解决方案是什么。
我不知道你是如何初始化第一次加载的,但你可以使用 UseEffect()
来解决你提到的小数位问题。
无限小数位...
onChange
是一个已经发生的事件,您可能想尝试将 onChange
更改为 onKeyDown
或 onKeyPress
,然后在您的代码中添加 e.preventDefault()
停止输入号码
if (val.includes(".") && val.split(".")[1].length > 2) {
e.preventDefault()
}
如果你想在'component did mount'时调用一个函数你可以使用
useEffect(yourFunction(){}, [])
我正在制作一个反应应用程序,它接受一个应该显示到小数点后两位的输入。当默认输入在小数点后有一个数字时,它应该在其后添加一个带有 0 的第二个数字。它还允许我添加无限数量的“0”,但将任何其他数字限制在小数点后 2 位。
图中有两个不同的问题:
案例一。 这是首次加载时输入的外观。首选显示为 1.60(两位小数)
案例二。 当前行为允许用户添加无限个 0(它限制在小数点后 2 位的任何其他数字)。预期行为应限制所有数字,包括小数点后 2 位的 0。
function ProductMaterial() {
const [name, setName] = useState("");
function handleChange(e) {
let val = e.target.value;
if (val.includes(".") && val.split(".")[1].length > 2) {
}
else {
setName(parseFloat(val));
setMaterialState(parseFloat(val));
}
}
return (
<div className="input-group-sm col-xs-2 material input-group">
<div className="input-group-prepend">
<span className="input-group-text">$</span>
</div>
<input
className="form-control"
type="number"
min="0.00"
onChange={handleChange}
value={product.material}
/>
</div>
);
}
这里是setMaterialState的代码。它更改 product.material 值,然后在 useEffect()
函数中调用 setMaterial()
。 setMaterial()
获取产品的 ID 和新的 material 值并将其保存到状态。
function setMaterialState(newMaterial) {
product.material = newMaterial;
}
useEffect(() => {
setMaterial(product.id, product.material);
}, [product.material]);
我知道这里的问题是在第一次加载时没有任何东西触发 onChange()
函数。我试过将 value={product.material}
设置为 value={product.material.toFixed(2)}
,但这使得修复输入变得困难。有没有什么好的方法可以在之前初始化它,也许使用 UseEffect()
语句?除此之外,我不确定为什么可以无限期地添加 0。
更新:
使用 Photonic 建议的 onKeyPress=
答案解决了前导 0 的第一个问题。
但是,我仍在努力解决当末尾为 0 时强制它保留两位小数的问题。我意识到不开始执行 1.60 的问题是由于它被转换为浮点值而不是字符串。我尝试做一个 UseEffect() [] 并用 product.material.toFixed(); 强制它转到小数点后 2 位;以及修改数据以 1.60 开头,但似乎强制保留两位小数的唯一方法是将其保留为字符串或使用 product.material.toFixed(2)
将其转换为字符串。输入 value={product.material}
中的值需要是一个数字才能正确执行计算并收集用户输入。我不确定最好的解决方案是什么。
我不知道你是如何初始化第一次加载的,但你可以使用 UseEffect()
来解决你提到的小数位问题。
无限小数位...
onChange
是一个已经发生的事件,您可能想尝试将 onChange
更改为 onKeyDown
或 onKeyPress
,然后在您的代码中添加 e.preventDefault()
停止输入号码
if (val.includes(".") && val.split(".")[1].length > 2) {
e.preventDefault()
}
如果你想在'component did mount'时调用一个函数你可以使用
useEffect(yourFunction(){}, [])