我在尝试弄清楚如何将值粘贴到多个输入字段中时遇到问题。我基本上正在构建一个验证屏幕,其中有 6 个单独的输入,最大长度为 1,并且希望能够粘贴整个 6 位代码,以便填充所有 6 个输入。我在 Jquery 中找到了几个解决方案,但不太确定如何在 React 中实现它。这是我的代码。
const Verify = ({ handleSubmit, method, rec, changeInput }) => {
const navigate = useNavigate();
const { email, phone } = rec
const send = method === 'email' ? { email: email } : { phone: phone }
const renderContent = () => {
const methodLabel = method === 'email' ? 'email address' : 'phone number'
return (
<>
<div id="back-grad"/>
<div className="col-md-8">
<div className='verify-text-section'>
<p className="verify-text pb-5">
Enter the PIN number we just sent to your {methodLabel}.
</p>
</div>
<div className="flex">
<input name='code-1' className='code-input mr-2' autoFocus maxLength='1' onChange={changeInput} />
<input name='code-2' className='code-input mr-2' maxLength='1' onChange={changeInput} />
<input name='code-3' className='code-input mr-2' maxLength='1' onChange={changeInput} />
<input name='code-4' className='code-input mr-2' maxLength='1' onChange={changeInput} />
<input name='code-5' className='code-input mr-2' maxLength='1' onChange={changeInput} />
<input name='code-6' className='code-input mr-2' maxLength='1' onChange={changeInput} />
</div>
<div className="verify-resend mt-3" onClick={resendPin}>Resend Code</div>
<div className="flex margin-set text-center">
<button className="btn btn-block text-white verify-btn">
<p className="verify-btn-text">VERIFY</p>
</button>
</div>
</div>
</>
)
}
return (
<>
{rec.email.length < 1 && rec.phone.length < 1 ? <Navigate to={'/auth'} />
:
<div className="d-flex align-items-center h-full">
<form className="container" onSubmit={e => onFormSubmit(e, handleSubmit)}>
<div className="row justify-content-center">
{renderContent()}
</div>
</form>
</div>
}
</>
)
}
这里是changeInput函数和handleChange函数,以及传递给组件的rec。
const [rec, setRec] = useState({
accept: false,
email: '',
phone: '',
pin: [],
})
const changeInput = (e) => {
const { maxLength, name, value } = e.target;
const [fieldName, fieldIndex] = name.split('-')
if(value.length >= maxLength) {
if(parseInt(fieldIndex, 10) < numOfFields) {
const nextSibling = document.querySelector(`input[name=${fieldName}-${parseInt(fieldIndex, 10) + 1}]`)
if(nextSibling !== null) {
nextSibling.focus()
}
}
setRec({
...rec,
pin:[...rec.pin, value]
})
}
}
const handleChange = (name, value) => {
if (name === 'mobile') name = 'phone'
const recState = {
...rec,
[name]: value,
}
setRec(recState)
}
如有任何帮助,我们将不胜感激。
最佳答案
不要在 React 组件中使用 document.querySelector
或 document.querySelectorAll
。相反,将这些元素直接添加到您的组件中。
这是一个使用 paste event 的最小可验证示例。 运行下面的示例并将 4 位数字粘贴到任意输入中。
function App() {
const [segments, setSegments] = React.useState(["","","",""])
function onPaste(event) {
const pasted = event.clipboardData.getData("text/plain")
setSegments(pasted.split("").slice(0, segments.length))
}
function randomPin() {
return Math.floor(Math.random() * 9000) + 1000
}
return <div>
<p>Copy <b>{randomPin()}</b> and paste into any input</p>
{segments.map((s, key) =>
<input key={key} value={s} onPaste={onPaste} />
)}
<pre>{JSON.stringify(segments)}</pre>
</div>
}
ReactDOM.render(<App/>, document.querySelector("#app"))
input { width: 2rem; }
pre { padding: 0.5rem; background-color: #ffc; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
在上面的程序中,无法手动输入 PIN。通过添加onChange
事件,可以支持手动录入。不要忘记在 onPaste
处理程序中使用 event.preventDefault
,否则所有值都将粘贴到单个段中。
function randomPin() {
return Math.floor(Math.random() * 9000) + 1000
}
function App({ pin }) {
const [segments, setSegments] = React.useState(["","","",""])
function onPaste(event) {
event.preventDefault() // ✅
const pasted = event.clipboardData.getData("text/plain")
setSegments(pasted.split("").slice(0, segments.length))
}
function update(index) { return event =>
setSegments([
...segments.slice(0, index),
event.target.value,
...segments.slice(index + 1)
])
}
return <div>
<p>Enter <b>{pin}</b> manually or copy/paste into any input</p>
{segments.map((s, key) =>
<input key={key} value={s} onPaste={onPaste} onInput={update(key)} />
)}
{segments.join("") == pin ? "✅" : "❌"}
<pre>{JSON.stringify(segments)}</pre>
</div>
}
ReactDOM.render(<App pin={randomPin()}/>, document.querySelector("#app"))
input { width: 2rem; }
pre { padding: 0.5rem; background-color: #ffc; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="app"></div>
关于reactjs - 在 React JS 中粘贴到多个输入字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71255377/