如何解决在受控的 React 数字输入中,如何修剪前导零?
在 React docs 中,它说在受控组件中,“React 状态是“唯一的事实来源””。这似乎是正确的,除非有前导零的情况。在下面的示例中,您可以看到输入是受控的,但在前导零的情况下,输入值并不总是与状态值匹配。
测试
键入前导零,因此该值类似于 0010
。
您可以看到 state
中的值是一个整数 10
,但输入显示的是 0010
。
我的第一个想法是这是因为组件实际上并没有重新渲染,这是真的。 10
和 10
之间没有状态变化,所以没有新的渲染。这是确认的,因为我们没有看到“渲染”console.log 触发。
因此,让我们确保更改该值。添加 2
以将 0010
更改为 00102
。 state 中的值现在是 102
,我们确认组件重新渲染...但前导零仍然存在于输入中。
这似乎不一致,因为我希望输入中的值始终与 state 中的值完全匹配。这是为什么?从数字输入中修剪前导零的可靠方法是什么?
// LEADING ZEROS INPUT TEST
// Step 1: type 0s into the input followed by any other digits
// Step 2: see that console log and val in `p` do not have leading 0's and input val does
const {useState} = React;
const App = () => {
const [val,setVal] = useState(10);
const handleChange = (evt) => {
const strVal = evt.currentTarget.value;
console.log('string',strVal,typeof strVal);
const intVal = parseInt(strVal,10) || 0; // || 0 bc '' returns NaN
console.log('int',intVal,typeof intVal);
setVal(intVal);
}
console.log('render',val);
return (
<div>
<p>{val}</p>
<input
type="number"
value={val}
onChange={handleChange}
/>
</div>
)
}
ReactDOM.render(
<App />,document.getElementById('root')
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
解决方法
既然您已经知道为什么,我将帮助您了解如何。
在我看来,一种从数字输入中修剪前导零的可靠方法是“模糊”,这会减少干扰并提供更好的用户体验。
const {useState,useCallback} = React;
const App = () => {
const [val,setVal] = useState(10);
const [strVal,setStrVal] = useState("10"); // To keep a reference of the real input value
const handleChange = (evt) => {
const inputVal = evt.currentTarget.value;
setStrVal(inputVal);
setVal(parseInt(evt.currentTarget.value,10) || 0);
}
const handleBlur = useCallback((evt) => {
setStrVal(val.toString());
},[val]);
return (
<div>
<p>{val}</p>
<input
type="number"
value={strVal}
onChange={handleChange}
onBlur={handleBlur}
/>
</div>
)
}
ReactDOM.render(
<App />,document.getElementById('root')
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。