skip to Main Content

I have a component that should expand if it is selected. Here’s my current approach:

<Element 
   ref={elementRef}
   style={{ height: isSelected ? `${elementRef.current.scrollHeight}px` : '0px' }} 
/>

Now, I’ve added routing, which parses the URL. For example, if I am at host:port/selected/1, the first element should automatically expand.

The URL parsing works fine, but it happens just at the beginning of the creation of the website.

This results that while the function is returning the JSX-Element, isSelected evaluates to true which causes an issue because the ref has not yet been initialized. (elementRef.current is null)

Or to put it in different words: the scrollHeight of a non-rendered object doesn’t make sense and React tells me so.

I’m struggling to figure out the best way to handle this. I think I need to use a different hook than useRef, but which one?

I tried using useState with the dependencies isSelected and elementRef which is not fired after rendering, but before (or during).

2

Answers


  1. Chosen as BEST ANSWER

    I managed to fix it by using useCallback

    So instead of

    <Element 
       ref={elementRef}
       style={{ height: isSelected ? `${elementRef.current.scrollHeight}px` : '0px' }} 
    />
    

    I have achieved it by using the useCallback hook which is called after each rendering pass:

    const detailRef = useCallback((element) => {
      if (!element) {
        return;
      }
    
      element.style.height = isExpanded ? `${element.scrollHeight}px` : '0px';
    }, [isExpanded]);
    
    // ...
    
    return (
    <Element ref={detailRef} />
    );
    
    

  2. If the ref is not set yet on the very initial render then you can likely use the Optional Chaining operator and a fallback value.

    Example:

    <Element 
       ref={elementRef}
       style={{
         height: isSelected
           ? `${elementRef.current?.scrollHeight ?? 0}px`
           : '0px'
       }} 
    />
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search