ForwardRef error with typescript and react-native

17,390

According to the definitions:

function forwardRef<T, P = {}>(Component: RefForwardingComponent<T, P>): ComponentType<P & ClassAttributes<T>>;
interface RefForwardingComponent<T, P = {}> {
    (props: P & { children?: ReactNode }, ref?: Ref<T>): ReactElement<any> | null;
    propTypes?: ValidationMap<P>;
    contextTypes?: ValidationMap<any>;
    defaultProps?: Partial<P>;
    displayName?: string;
}

ref is an optional argument, try the following:

Inside a class create a ref object with a type parameter equal to your desired target (in my case div but View also works in react-native)

private divRef: React.RefObject<div> = React.createRef();

In the interface that represents the props for the forwarded component expose it as an optional property

interface Props {
  ref?: React.RefObject<div>;
}

Declare the forwarded component with the type React.ComponentType

const ComponentWithForwardedRef: React.ComponentType<Props> = 
  React.forwardRef((props: Props, ref?: React.Ref<div>) => (
    <div ref={ref}>{props.message}</div>
  ));

When an instance of the component with the forwarded ref is created send the created ref object as a prop

<ComponentWithForwardedRef ref={this.divRef} />

All in one:

import * as React from "react";
import { render } from "react-dom";

interface Props {
  message: string;
  ref?: React.RefObject<div>;
}

const ComponentWithForwardedRef: React.ComponentType<Props> = 
  React.forwardRef((props: Props, ref?: React.Ref<div>) => (
    <div ref={ref}>{props.message}</div>
  ));

class App extends React.Component<Props> {
  private divRef: React.RefObject<div> = React.createRef();

  public componentDidMount() {
    const div = this.divRef.current;
    // check the console!
    console.log(div);
  }

  public render() {
    return (
      <ComponentWithForwardedRef ref={this.divRef} {...this.props} />
    )
  }
}

render(<App message="hello world" />, document.getElementById("root"));

Link for posterity: https://codesandbox.io/s/6v152q394k

Dependencies (reference purposes)

"@types/react": "^16.3.11",
"@types/react-native": "^0.55.19",
"react-native": "0.55.2",
"typescript": "^2.8.1"
Share:
17,390

Related videos on Youtube

bernatfortet
Author by

bernatfortet

Updated on June 29, 2022

Comments

  • bernatfortet
    bernatfortet almost 2 years

    I'm getting a ts error when using forwardRef

    // [ts] Property 'forwardRef' does not exist on type 'typeof React'.
    const MyComponent = React.forwardRef((props: Props, ref: any) => ...
    

    In React Native the parent component is throwing this error:

    Invariant Violation: Element type is invalid: expected a string (for build-in components) or a class/function (for composite components) but got: object
    

    Any idea on how to solve it?

  • tettoffensive
    tettoffensive almost 4 years
    In my case it was React.Ref<HTMLDivElement>. I'm also no sture why you're listing ref in the interface Props. At least for me this was not necessary and doesn't make sense since it's not part of props: Props