skip to Main Content

This is my React Component. and when I enter total 6 digits in Otp Input; the onComplete method is getting invoked which will trigger handleSubmit function and It should print the latest value of state otp. But it is just printing 5 digits of input. How to solve this ?

function OtpForm() {

    const [otp, setOtp] = useState('');

    function handleSubmit() {
        console.log(otp);
    };

    return (
        <form>
            <MuiOtpInput
                value={otp}
                onChange={(val) => { setOtp(val); }}
                validateChar={(val) => !isNaN(val)}
                onComplete={() => { handleSubmit(); }}
                length={6}
            />
        </form>
    );
}

3

Answers


  1. By using useEffect with [otp] as its dependency array, the handleSubmit function will be triggered whenever the otp state changes. This ensures that handleSubmit will have access to the latest value of otp. Also, remove the call to handleSubmit from the onComplete prop, as it’s now handled by the useEffect hook.

    import { useState, useEffect } from 'react';
    
    function OtpForm() {
    
        const [otp, setOtp] = useState('');
    
        useEffect(() => {
            //--->This will trigger every time 'otp' changes
            handleSubmit();
        }, [otp]); //--->Watching for changes in 'otp'
    
        function handleSubmit() {
            console.log(otp);
        };
    
        return (
            <form>
                <MuiOtpInput
                    value={otp}
                    onChange={(val) => { setOtp(val); }}
                    validateChar={(val) => !isNaN(val)}
                    onComplete={() => { /* No need for handleSubmit here */ }}
                    length={6}
                />
            </form>
        );
    }
    Login or Signup to reply.
  2. In tbis code the setOtp function takes a callback that receives the previous state as an argument. This ensures that you’re using the latest state when updating it. In the onComplete handler, I’ve modified it to pass the previous OTP value to the handleSubmit function.

    Try this code:-

    function OtpForm() {
        const [otp, setOtp] = useState('');
    
        function handleSubmit() {
            console.log(otp);
        }
    
        return (
            <form>
                <MuiOtpInput
                    value={otp}
                    onChange={(val) => { setOtp(val); }}
                    validateChar={(val) => !isNaN(val)}
                    onComplete={() => { setOtp((prevOtp) => { handleSubmit(prevOtp); }); }}
                    length={6}
                />
            </form>
        );
    }
    
    Login or Signup to reply.
  3. React doesn’t update the state until it renders again, and considering changing state is asynchronous, it takes a bit time to update the value, thats why you are not getting the latest value. Best way is to update it using a callback function, so it would reflect the latest value, so your code would be like thisL

    function OtpForm() {
    
    const [otp, setOtp] = useState('');
    
    function handleSubmit() {
        console.log(otp);
    };
    
    return (
        <form>
            <MuiOtpInput
                value={otp}
                onChange={(val) => { setOtp(()=>val); }}
                validateChar={(val) => !isNaN(val)}
                onComplete={() => { handleSubmit(); }}
                length={6}
            />
        </form>
    );
    

    }

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search