leefsmp/Re-Flex

React `ref` of element inside `<ReflexElement>` is not properly on first render

Closed this issue · 2 comments

akphi commented

Description

I come across one strange phenomenon while using react-reflex. When we set a ref for a <div> that nested inside a <ReflexElement>, at the first rendering, even within the useEffect, my ref is null. I bet I miss something here since this is quite a common use case: e.g. I grab the ref so I can focus on an <input> or do some dimension measuring, etc.

How to reproduce the issue?

Please see the snippet below (I took the basic example in README):

const App = (props: {}) => {
  const ref = useRef<HTMLDivElement>(null);
  console.log("ref", ref);


  useEffect(() => {
    console.log(ref.current); // this will be null
  }, []);


  return (
    <ReflexContainer orientation="vertical">
      <ReflexElement className="left-pane">
        <div ref={ref} className="pane-content">
          Left Pane (resizeable)
        </div>
      </ReflexElement>


      <ReflexSplitter />


      <ReflexElement className="right-pane">
        <div className="pane-content">Right Pane (resizeable)</div>
      </ReflexElement>
    </ReflexContainer>
  );
};

The full code can be found at: https://github.com/akphi/issue-repo/tree/react-reflex-no-ref

Expected behavior

I would expect in the useEffect block, my ref is not null.

Actual behavior

My ref is null.

Additional context

Now, if I do some resizing and use onResize on <ReflexElement>, and then I console.log the ref, I can actually see the ref being populated. I'm really puzzled by this and I bet I might have missed something. Could you kindly give me some guidance here?

Thank you so much!


If instead, I turn the nested content into another component, then it's fine though. I guess this is the workaround, but I still don't understand the behaviour mentioned above.

const SubComp: React.FC<{}> = () => {
  const ref = useRef<HTMLDivElement>(null);
  console.log("ref", ref);

  useEffect(() => {
    console.log(ref.current); // this will NOT be null
  }, []);

  return (
    <div ref={ref} className="pane-content">
      Left Pane (resizeable)
    </div>
  );
};

const App = (props: {}) => {
  return (
    <ReflexContainer orientation="vertical">
      <ReflexElement className="left-pane">
        <SubComp />
      </ReflexElement>
      <ReflexSplitter />
      <ReflexElement className="right-pane">
        <div className="pane-content">Right Pane (resizeable)</div>
      </ReflexElement>
    </ReflexContainer>
  );
};

Is this related to the issue that was encountered here?

akphi commented

Ah, my use case is actually exactly that, I have a <canvas>. Thank you so much for the detailed explanation!