React受控组件输入值格式化:添加千分位逗号的实现方案咨询
React受控组件实现千分位输入的解决方案
要解决受控组件中千分位格式化后光标跳转的问题,核心是在格式化文本后精准恢复光标位置,以下是具体实现方案:
实现思路
- 保留输入框的DOM引用,用于后续操作光标
- 处理输入时,先记录当前光标位置
- 提取输入中的纯数字并格式化为千分位格式
- 根据原始光标前的数字数量,计算格式化后的光标位置
- 在组件更新后,将光标恢复到计算后的正确位置
完整代码
import { useState, useRef, useEffect } from 'react'; const NumberInput = () => { const [value, setValue] = useState(''); const inputRef = useRef(null); const [cursorPos, setCursorPos] = useState(0); const handleChange = (event) => { const inputValue = event.target.value; const selectionStart = event.target.selectionStart; // 过滤非数字字符,保留纯数字 const rawDigits = inputValue.replace(/\D/g, ''); // 给纯数字添加千分位逗号 const formattedValue = rawDigits.replace(/\B(?=(\d{3})+(?!\d))/g, ','); // 计算原始光标位置前的数字总数 const digitsBeforeCursor = inputValue.slice(0, selectionStart).replace(/\D/g, '').length; // 计算格式化后光标应处的位置:数字数 + 前面的逗号数量 let newCursorPos = digitsBeforeCursor + Math.floor((digitsBeforeCursor - 1) / 3); // 处理边界:光标不能超出文本长度 newCursorPos = Math.min(newCursorPos, formattedValue.length); setValue(formattedValue); setCursorPos(newCursorPos); }; // 当输入值或光标位置更新后,恢复光标到正确位置 useEffect(() => { if (inputRef.current) { inputRef.current.setSelectionRange(cursorPos, cursorPos); } }, [value, cursorPos]); return <input type="text" ref={inputRef} value={value} onChange={handleChange} />; }; export default NumberInput;
关键细节说明
- 光标位置计算:通过统计原始光标前的数字数量,结合千分位逗号的规律(每3个数字添加一个逗号),计算出格式化后的光标位置,确保光标始终跟随用户输入的位置
- 受控组件规范:全程通过
useState管理输入值,没有直接修改event.target.value,符合React受控组件的设计要求 - 边界处理:处理了输入为空、光标在末尾等极端情况,避免光标位置越界
内容的提问来源于stack exchange,提问作者hyunyi
相关产品推荐
相关产品推荐

