Search code examples
reactjsreact-hooksref

React forwardref current is always null


So, I'm trying to implement the react forwardref example for my component, as I want to control a scrollbar inside.

Here's what I have:

const MessagesFC = React.forwardRef((props, ref) => {       
    return <Flex
        className={"Messages"}
        direction={"Column"}
        ref={ref}>
        {messages}
    </Flex>
});

const scrollDivRef = React.createRef<any>();

React.useEffect(() => {
    scrollDivRef.current?.scrollIntoView({ behavior: "smooth"})
}, [ scrollDivRef, chatRoom.messages ])

Inside my return(), the component is added like this:

<MessagesFC 
    ref={scrollDivRef}/>

Seems to be setup just like in the example.

However, when executing this code, the scrollDivRef.current is always undefined.

So, where did I go wrong?

Screenshot of my code:

enter image description here


Solution

  • First of all you must note that in a functional component you must use useRef to define ref and not React.createRef since useRef will return you the same ref instance everytime whereas React.createRef will give you a different ref instance

    Second, MessageFC component needs to be defined outside of the Parent component not inside of its body, otherwise a new instance of it is created again and you will always see the component getting remounted which is why the scrollDivRef inside of useEffect will not give you accurate information

    Third You don't need to add scrollDivRef as a dependency to useEffect.

    const MessagesFC = React.forwardRef((props, ref) => {       
        return <Flex
            className={"Messages"}
            direction={"Column"}
            ref={ref}>
            {messages}
        </Flex>
    });
    
    const Parent = () => {
        const scrollDivRef = React.useRef<any>();
    
        React.useEffect(() => {
            scrollDivRef.current?.scrollIntoView({ behavior: "smooth"})
        }, [ chatRoom.messages ]);
    
        ...
    }