React Native pass ref to functional component that is wrapped with a HOC

Viewed 1702

I am trying to pass a ref from the parent to its child. The child is a functional component, so I am doing:

// Child
const Configuration = forwardRef((props, ref) => {
    const { colors } = useTheme();

    const fall = useRef(new Animated.Value(1)).current;

    return <></>
});

And all is working good. But when I try to do

export default withFirebase(Configuration);

The problem appears...

Here is the HOC Component:

import React from "react";

import { FirebaseContext } from "../Firebase/";

const withFirebase = (Component) => (props) => (
  <FirebaseContext.Consumer>
    {(firebase) => <Component {...props} firebase={firebase} />}
  </FirebaseContext.Consumer>
);

export default withFirebase;

Any ideas how to pass a ref to a functional component that is wrapped on a HOC?

I have tried to do something like this:

const Configuration = forwardRef((props, ref) => withFirebase(() => {
    const { colors } = useTheme();

    const fall = useRef(new Animated.Value(1)).current;

    return <></>
}));

export default Configuration;

but didn't work. Thank you.

1 Answers

The only way to pass props with functional components is to use React.forwardRef(). But, if you are using it, why do you get an error (I suppose it is "Functional components doesn't accept refs)?

If you don't wrap the component in the HOC all will work fantastic, so the problem is with your HOC.

const withFirebase = (Component) => (props) => (
  <FirebaseContext.Consumer>
    {(firebase) => <Component {...props} firebase={firebase} />}
  </FirebaseContext.Consumer>
);

A HOC is just another component that receives a "WrappedComponent" to generalize common situations in your app. You have implemented it as a functional component so you can perfectly use React.forwardRef to make it receive refs.

Just like this:

const withFirebase = (Component) => React.forwardRef((props, ref) => (
  <FirebaseContext.Consumer>
    {(firebase) => <Component ref={ref} {...props} firebase={firebase} />}
  </FirebaseContext.Consumer>
));

But maybe, you are using your HOC in components that doesn't expect to use refs... In this situation, don't change your HOC, just pass the ref to the functional component as a prop. Like this:

const Configuration = withFirebase(function Configuration(props) {
  const { colors } = useTheme();

  const { inputRef } = props;

  const fall = useRef(new Animated.Value(1)).current;

  return <></>;
});


export default forwardRef((props, ref) => ( // <----- The magic
  <Configuration {...props} inputRef={ref} />
));

As you are passing the ref as a prop, you cannot do this:

export default forwardRef((props, ref) => ( // <----- The magic
  <Configuration {...props} ref={ref} />
));

Because the attribute "ref" is reserved by React, and will only expect refs as value.

That's all.

Related