Search code examples
javascriptreactjsuse-effectuse-ref

React useRef is not setting even in useEffect


I am attempting to show an image in a random position according to dynamic dimensions using a ref. However, when getting the useRef's current value, I recieve undefined likely because the useRef's target div hasn't loaded yet.

To overcome this, I am using a useEffect to wait for the target div to load.

However, when I run the program the image does not move because the useRef's current value remains at 0. The

import './MouseAim.css'
import '../Game.css'

import React, {useEffect, useRef, useState} from 'react'

import TargetImg from '../../../assets/Target.png'
import _ from "lodash";

function MouseAim() {
    const [start, setStart] = useState(true)
    const [target, setTarget] = useState(true)
    const elementDimensions = useRef()


    //wait for elementDimensions to be set
    useEffect(() => {
        console.log('elementDimensions', elementDimensions.current?.clientHeight)
    } , [elementDimensions])

    return (
        <div>
            <div className="main-container">
                {
                        start ?

                            <div ref={elementDimensions} className="aim-container">
                                {
                                    target ?
                                            <input 
                                                className="target" 
                                                type="image" 
                                                style={{position: "relative", left:elementDimensions.current?.clientHeight+"px" , top:_.random(0, elementDimensions.current?.clientHeight)+"px"}}
                                                onClick={() => console.log("hello")} 
                                                src={TargetImg} 
                                                alt="target"
                                            />
                                    :null
                                }
                            </div>

                        :
                            <div className="start-container">
                                <input className="start-button" type="button" value="Start Game" onClick={() => setStart(true)}/>
                            </div>
                }
            </div>
        </div>
    )
}

export default MouseAim

Solution

  • Just set your target initial state to 'false', then set it to true when 'ref' is ready

    Try this one:

    const [start, setStart] = useState(true)
    const [target, setTarget] = useState(false)
    const elementDimensions = useRef()
    
    
    //wait for elementDimensions to be set
    useEffect(() => {
        console.log('elementDimensions', elementDimensions.current?.clientHeight)
        setTarget(true)
    } , [elementDimensions])