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?
React forwardRef is a method that allows parent components pass down (i.e., “forward”) refs to their children. Using forwardRef in React gives the child component a reference to a DOM element created by its parent component. This then allows the child to read and modify that element anywhere it is being used.
The forwardRef hooks allows React users to pass refs to child components. The ref can be created and referenced with useRef or createRef and then passed in a parent component. Using forwardRef instead of useRef is useful when a ref needs to be accessed in a parent component.
On this case, we need to change the Input Component to use the forwardRef. import React, { forwardRef } from "react"; const Input = (props, ref) => <input ref={ref} type="text" style={style} />; export default forwardRef(Input);
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With