货币输入不将 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 更改为 onKeyDownonKeyPress,然后在您的代码中添加 e.preventDefault() 停止输入号码

if (val.includes(".") && val.split(".")[1].length > 2) {
   e.preventDefault()
}

如果你想在'component did mount'时调用一个函数你可以使用

useEffect(yourFunction(){}, [])