Reputation: 1499
I'm trying to build and type a HOC which just wraps a component in an ApolloProvider. I would like to be able to forward the ref on to the wrapped component. However, when I try and pass props along in the forwardRef component I'm getting type errors
Somewhere along my research spree I stumbled upon an answer that talked about generics being the issue.
const withProvider = function<P>(WrappedComponent: React.ComponentClass<P>) {
type Props = P & { forwardedRef?: React.Ref<any> }
class WithProvider extends React.Component<Props> {
render() {
const { forwardedRef, ...props } = this.props
return (
<ApolloProvider client={client}>
<WrappedComponent {...props} ref={forwardedRef} />
</ApolloProvider>
)
}
}
hoistNonReactStatics(WithProvider, WrappedComponent)
return React.forwardRef((props, ref) => (
<WithProvider {...props} forwardedRef={ref} />
))
}
Gives me the error:
Type '{ forwardedRef: string | ((instance: {} | null) => any) | RefObject<{}> | undefined; children?: ReactNode; }' is not assignable to type 'Readonly<Props>'
To me these should match up and the former should be assignable to the latter. The only thing I can think of is that Readonly<Props>
contains a generic.
Can someone point me in the right direction?
Upvotes: 6
Views: 1610
Reputation: 10085
Finally, I found the solution.
All you have to do is give the type of props (in
React.forwardRef
) as the type received which isP
.
return React.forwardRef((props:P, ref) => (
<WithProvider {...props} forwardedRef={ref} />
));
Complete Code:
const withProvider = function<P>(WrappedComponent: React.ComponentClass<P>) {
type Props = P & { forwardedRef?: React.Ref<any> }
class WithProvider extends React.Component<Props> {
render() {
const { forwardedRef, ...props } = this.props
return (
<ApolloProvider client={client}>
<WrappedComponent {...props} ref={forwardedRef} />
</ApolloProvider>
)
}
}
hoistNonReactStatics(WithProvider, WrappedComponent)
return React.forwardRef((props:P, ref) => (
<WithProvider {...props} forwardedRef={ref} />
))
}
Upvotes: 1