The React useState() hooks stores undefined always even the data that is to be stored logs correctly using console.log();

Viewed 426

Here is the where I am having the problem,

const handleCLick = () => {
        const parsedId = getYouTubeID(videoLink);
        console.log(parsedId);
        setVideoId(parsedId);
        console.log(videoId);
    }

Here when I am trying to log the 'parsedId' it logs the data correctly

ioNng23DkIM

And after using the setVideoId() function when I try to log the value it returns undefined

undefined

Here is a snap shot of the log output.

enter image description here

Home.js code:

import React, { useRef, useState } from "react";
import { Link } from "react-router-dom";
import getYouTubeID from 'get-youtube-id';

function Home(props) {
    const [videoLink, setVideoLink] = useState();
    const [isBool, setBool] = useState(false);
    const [videoId, setVideoId] = useState();
    const urlRef = useRef();

    const handleChange = (event) => {
        setVideoLink(event.target.value);
        if (urlRef.current.value === '') {
            alert('Please enter a URL');
            setBool(true);
        } else {
            setBool(false);
        }
    }

    const handleCLick = () => {
        const parsedId = getYouTubeID(videoLink);
        console.log(parsedId);
        setVideoId(parsedId);
        console.log(videoId);
    }

    return (
        <section className="homeLayout">
            <div className="logo-display">
                <img className="logo-img" alt="logo" src="./logo.png" />
                <h1>WatchIt</h1>
            </div>
            <div className="searchlayer">
                <form>
                    <input ref={urlRef} id="videoLink" placeholder="Enter the youtube video URL:" onBlur={handleChange} required />
                    <Link style={{ pointerEvents: isBool ? 'none' : 'initial' }} to={`/play?=${videoId}`} onClick={handleCLick}>Play</Link>
                </form>
            </div>
        </section>
    );
}

export default Home;
2 Answers

You can use useEffect to solve your problem.

Use effect will listen to you state change n then you can perform logic in there.

The problem you're facing is because setState will set the value eventually, not immediately (Usually this means the update will be visible when the component is rendered again). If you want to do something after the value is set, you need to use useEffect.

Splitting your handleClick we get,

const handleCLick = () => {
    const parsedId = getYouTubeID(videoLink);
    console.log(parsedId);
    setVideoId(parsedId); // Queue the change for `videoId`
}

useEffect(() => {
    console.log(videoId); 
}, [videoId]); // Call this function when the value of `videoId` changes
Related