'once deleting out of input, focus previous input react

I am having issues trying to focus on a previous input once I delete out of the input that I am in. I have 6 inputs, all with a maxLength of 1. When I press the backspace key I would like to delete the value and move to the previous input. I have tried a variety of things but nothing seems to work how I need.

Here is my code

This is the Auth component which is passing props to verify (the page with the inputs)

const Auth = ({ sub }) => {
    let params = useParams();
    const navigate = useNavigate();

    const [rec, setRec] = useState({
        accept: false,
        email: '',
        phone: '',
        pin: ['', '', '', '', '', '']
    })

    const onPaste = (event) => {
        event.preventDefault()
        const pasted = event.clipboardData.getData("text/plain")
        setRec({ ...rec, pin: pasted.split("").slice(0, rec.pin.length) })
        // target event last sibling
        event.target.parentNode.lastChild.focus()
    }

    function update(event, index) {
        event.preventDefault()
        setRec({
            ...rec, pin: [
                ...rec.pin.slice(0, index),
                event.target.value,
                ...rec.pin.slice(index + 1)
            ]
        })
    }

    const handleFocus = (event) => {
        if (event.target.nextSibling)
            event.target.nextSibling.focus();

        // if value is deleted, focus previous sibling

        // if all siblings are empty, focus first sibling
        if (event.target.value === '' && event.target.previousSibling === null)
            event.target.parentNode.firstChild.focus()

    }

    const onKeyPress = (event) => {
        // if backspace is clicked, go to previous input
        if (event.key === 'Backspace' && event.target.value === '') {
            event.target.previousSibling.focus()
        }
    }

    const handleChange = (name, value) => {
        if (name === 'mobile') name = 'phone'
        const recState = {
            ...rec,
            [name]: value,
        }
        setRec(recState)
    }

    const toggleAccept = () => {
        if (!rec.accept) {
            setRec({
                ...rec,
                accept: true
            });
        } else {
            setRec({
                ...rec,
                accept: false
            });
        }

    }

    const handleSubmit = async () => {
        const { accept, email, phone } = rec

        if (params.method === 'email' && !email) return app.actions.setError('Enter an email')
        else if (params.method !== 'email' && !phone) return app.actions.setError('Enter a phone number')

        const send = params.method === 'email' ? { email } : { phone }

        if (!accept) return app.actions.setError('Please accept the terms & conditions')
        try {
            await app.actions.setLoading(true)
            // if there is already a user, just login, else create user first
            await user.actions.login(send)
            await app.actions.setLoading(false)
            navigate(`/auth/verify/login/${params.method || 'phone'}`)
        } catch (e) {
            if (e.response && e.response.status === 404) {
                // try join
                await user.actions.join(send)
                await app.actions.setLoading(false)
                return navigate(`/auth/verify/join/${params.method || 'phone'}`)
            }
            await app.actions.setLoading(false)
            await app.actions.setError(e)
        }
    }

    const handleVerify = async ({ context, method }) => {
        const { email, phone, pin } = rec
        const joinPin = pin.join('');

        if (method === 'email' && !email) return app.actions.setError('Enter an email')
        else if (method !== 'email' && !phone) return app.actions.setError('Enter a phone number')

        const send = method === 'email' ? { email } : { phone }

        await app.actions.setError(null)
        try {
            await app.actions.setLoading(true)
            if (context === 'login') {
                await user.actions.loginVerify({
                    ...send,
                    pin: joinPin,
                })
            } else {
                await user.actions.verify({
                    ...send,
                    pin: joinPin,
                })
            }

            await app.actions.init()
            await app.actions.setLoading(false)

            navigate('/')
        } catch (e) {
            await app.actions.setLoading(false)
            await app.actions.setError(e)
        }
    }

    return (
        <>
            {sub ?
                <Verify
                    context={params.context}
                    handleChange={handleChange}
                    handleFocus={handleFocus}
                    handleSubmit={() => handleVerify({ context: params.context, method: params.method })}
                    onKeyPress={onKeyPress}
                    method={params.method}
                    paste={onPaste}
                    update={update}
                    rec={rec} />
                :
                <Jogin
                    handleChange={handleChange}
                    handleSubmit={handleSubmit}
                    method={params.method}
                    toggleAccept={toggleAccept}
                    rec={rec} />
            }
        </>
    )
}

export default Auth

and here is the verify component

import React from 'react'
import { onFormSubmit } from '../../utility/form'
import { Navigate, useNavigate } from 'react-router-dom'
import user from '../../model/user'
import app from '../../model/app'

const Verify = ({ handleSubmit, method, rec, paste, update, handleFocus, onKeyPress }) => {
    const navigate = useNavigate();
    const { email, phone } = rec
    const send = method === 'email' ? { email: email } : { phone: phone }

    const resendPin = async () => {
        try {
            await app.actions.setLoading(true)
            // if there is already a user, just login, else create user first
            await user.actions.login(send)
            await app.actions.setLoading(false)
            navigate(`/auth/verify/login/${method || 'phone'}`)
        } catch (e) {
            if (e.response && e.response.status === 404) {
                // try join
                await user.actions.join(send)
                await app.actions.setLoading(false)
                return navigate(`/auth/verify/join/${method || 'phone'}`)
            }
            await app.actions.setLoading(false)
            await app.actions.setError(e)
        }
    }

    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">
                        {rec.pin.map((s, key) => (
                            <input key={key} className='code-input mr-2' value={s} maxLength='1' onPaste={(e) => paste(e)} onKeyDown={e => onKeyPress(e)} onInput={(e) => update(e, key)} onChange={(e) => handleFocus(e)} inputMode='numeric' autoFocus={key === 0} />
                        ))}
                    </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>
            }
        </>
    )
}

export default Verify

any help is appreciated!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source