I am having an issue trying to figure out how to paste a value into multiple input fields. I am basically building a verify screen with 6 separate inputs that have a maxLength of 1, and want to be able to paste the entire 6 digit code so that is populates all 6 inputs. I have found several solutions in Jquery but not quite sure how to pull it off in react. Here is my code.
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>
            }
        </>
    )
}
and here is the changeInput function and handleChange function, as well as what rec looks like being passed to the component.
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)
    }
any help would be appreciated.
Don't use document.querySelector or document.querySelectorAll inside of your React component. Instead add those elements directly to your component.
Here's a minimal verifiable example using the paste event. Run the example below and paste the 4-digit number into any input.
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>In the program above, there is no way to type the PIN in manually. By adding a onChange event, manual entry can be supported. Don't forget to use event.preventDefault in the onPaste handler otherwise all values will be pasted into a single segment.
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>If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With