Emil
Emil

Reputation: 145

How to return html tags in useEffect?

If i run a console.log(props.lightbox) within the if(props.lightbox) statement i get a true prompt, so why isn't the return statement being passed out?

The reason why i have 2 different functions, is because i want to do some smooth animation with css. If i run it without it being wrapped in an useEffect method, it works as expected, but i want it to wait 2 seconds before returning the empty div, and not wait at all when returning the lightbox-container

import React, { useEffect } from 'react'

function LightboxContent(props){
    useEffect(() => {
        const intervalId = setTimeout(() => {
            if(props.lightbox){
                return(
                    <div className="lightbox-container">
                        <img src={props.pitem.src} alt={props.pitem.title}></img>
                            <div className="lightbox-text">
                                <div className="lightbox-h1">
                                    <h1>{props.pitem.title}</h1>
                                    <h2>{'(' + props.pitem.type + ')'}</h2>
                                </div>
                                <h2>{props.pitem.director ? "Director: " + props.pitem.director : null || props.pitem.production ? "Production: " + props.pitem.production : null}</h2>
                                <h2>{"role: " + props.pitem.role}</h2>
                            </div>
                    </div>
                )
            } else {
                return(
                    <div></div>
                )
            }
        }, props.lightbox ? 2000 : 0);
        return () => clearInterval(intervalId);
    }, [props.lightbox]);      
}

function Lightbox(props){
    return(
        <div id="lightbox" className={props.lightbox ? "lightbox-content-container-active" : ""} onClick={() => props.click()}>
            {LightboxContent(props)}
        </div>
    )
}

Upvotes: 0

Views: 3533

Answers (1)

diogominhava
diogominhava

Reputation: 66

The LightboxContent component is not rendering anything. The useEffect hook just runs when a components first mounts, but you don't have a return statement in it. Another note is that you're clearing the setTimeout with clearInterval, it should be clearTimeout. If I understand correctly, this should work:

function LightboxContent(props){

    const [canRender, setCanRender] = useState(false);
    
    useEffect(() => {

        const intervalId = setTimeout(() => {
            setCanRender( true );
        }, props.lightbox ? 2000 : 0);

        return () => clearTimeout(intervalId);
    }, [props.lightbox]);      

    if(canRender) {
        return(
            <div className="lightbox-container">
                <img src={props.pitem.src} alt={props.pitem.title}></img>
                    <div className="lightbox-text">
                        <div className="lightbox-h1">
                            <h1>{props.pitem.title}</h1>
                            <h2>{'(' + props.pitem.type + ')'}</h2>
                        </div>
                        <h2>{props.pitem.director ? "Director: " + props.pitem.director : null || props.pitem.production ? "Production: " + props.pitem.production : null}</h2>
                        <h2>{"role: " + props.pitem.role}</h2>
                    </div>
            </div>
        )
    } else {
        return(
            <div></div>
        )
    }

}

Essentially the component is rendered after the timeout is reached.

Upvotes: 1

Related Questions