javascriptreactjs

How to use useRef variable in useEffect once its been assigned and cant use ref from forwardRef in useEffect


This is my code

import { useEffect, useRef, useState } from "react";
import PostContainer from "./postContainer.jsx"

export function App(props) {
  const postContainerRef=useRef()
  useEffect(()=>{
    console.log(postContainerRef.current)
  },[postContainerRef])
  return (
    <div className='App'>
      <h1>Hello React.</h1>
      <PostContainer 
      ref={postContainerRef}
      some_prop={"meow"} />
    </div>
  );
}

here I want to use the postContainerRef once it's been set but its just logging undefined. I tried using [postContainerRef.current] as the dependency array but it also did nothing.

import { useState, useEffect, useRef, forwardRef } from "react";

const PostContainer = forwardRef((props, ref) => {
    useEffect(()=>{
      console.log(ref.current)
    },[ref])
    return <>
    <div>This is Container</div>
    </>
})

export default PostContainer

I also want to access the Container element once its been rendered but it is also logging undefined.

Playcode playground


Solution

  • The issue you're facing is related to how useRef and forwardRef work together with useEffect. Here are the key points to address:

    1 - The useRef object (postContainerRef) does not trigger re-renders when its current property is updated. Therefore, it won't work as a dependency in useEffect.

    2 - When using forwardRef, you should pass the ref to the actual DOM element you want to reference. Here's a revised version of your code to ensure the ref is properly set and can be used in useEffect:

    App Component

    import { useEffect, useRef } from "react";
    import PostContainer from "./PostContainer";
    
    export function App(props) {
      const postContainerRef = useRef(null);
    
      useEffect(() => {
        if (postContainerRef.current) {
          console.log(postContainerRef.current);
          // You can now use postContainerRef.current here
        }
      }, []);
    
      return (
        <div className='App'>
          <h1>Hello React.</h1>
          <PostContainer ref={postContainerRef} some_prop={"meow"} />
        </div>
      );
    }
    
    

    PostContainer Component

    import { useEffect, forwardRef } from "react";
    
    const PostContainer = forwardRef((props, ref) => {
      useEffect(() => {
        if (ref.current) {
          console.log(ref.current);
          // You can now use ref.current here
        }
      }, [ref]);
    
      return (
        <div ref={ref}>
          This is Container
        </div>
      );
    });
    
    export default PostContainer;
    
    

    Explanation

    1-App Component:

    2-PostContainer Component:

    This way, the ref is properly assigned to the DOM element, and you can use it in your useEffect hooks both in the parent and the child components.