[英]React.forwardRef with generic Props type in flow
I'm trying to add React.forwardRef
to an already existing component that looks like this:我正在尝试将React.forwardRef
添加到如下所示的现有组件中:
type Props<T> = {
someProp: T,
}
const Component = <T>({someProp}: Props<T>) => {...}
Now this is component uses Props<T>
, where T
is some generic type.现在这是组件使用Props<T>
,其中T
是某种通用类型。 I'm having difficulties adding React.forwardRef
and having no errors and no compromises on typing.我在添加React.forwardRef
遇到了困难,并且在打字时没有错误和妥协。
Here are some things I've tried:以下是我尝试过的一些事情:
// Complains T doesn't exist
const Component = React.forwardRef<Props<T>, HTMLElement>((props, ref) => {...})
// Multiple errors
type Props<T> = {
value: T,
onChange: T => void,
}
const ChildComponent = <T>() => React.forwardRef<Props<T>, HTMLDivElement>((props, ref) => {
return <div ref={ref}>123</div>;
});
const ParentComponent = () => {
const [value, setValue] = React.useState(123);
const onChange = newValue => setValue(newValue);
return <ChildComponent />;
};
===============================================================================================
All branches are incompatible:
• Either inexact AbstractComponent [1] is incompatible with exact React.Element [2].
• Or AbstractComponent [1] is incompatible with React.Portal [3].
• Or property @@iterator is missing in AbstractComponent [1] but exists in $Iterable [4].
../x.jsx
7│ onChange: T => void,
8│ }
9│
10│ const ChildComponent = <T>() => **React.forwardRef<Props<T>, HTMLDivElement>((props, ref) => {
11│ return <div ref={ref}>123</div>;
12│ })**;
13│
14│ const ParentComponent = () => {
15│ const [value, setValue] = React.useState(123);
/private/tmp/flow/flowlib_1eb3ba5b/react.js
[2] 18│ | React$Element<any>
[3] 19│ | React$Portal
[4] 20│ | Iterable<?React$Node>;
:
[1] 297│ ): React$AbstractComponent<Config, Instance>;
Do you know how to use forwardRef with generic types in flow?你知道如何在流中使用具有泛型类型的 forwardRef 吗?
Does something like this work for you?像这样的事情对你有用吗?
import React, { forwardRef } from 'react';
function GenericComponent<T>(props: { someProp: T }) {
return null;
}
const ForwardedRefGenericComponent = forwardRef(
(props, ref) => <GenericComponent ref={ref} {...props} />
);
function App() {
// Examples of using ForwardedRefGenericComponent
return (
<div>
<ForwardedRefGenericComponent someProp={42} />
<ForwardedRefGenericComponent someProp={"abc"} />
<ForwardedRefGenericComponent someProp={true} />
<ForwardedRefGenericComponent someProp={["x", "y"]} />
<ForwardedRefGenericComponent someProp={{ x: "y" }} />
</div>
);
}
Flow should be smart enough to infer the types for you so there's no need to declare the types explicitly for ForwardedRefGenericComponent
. Flow 应该足够智能,可以为您推断类型,因此无需为ForwardedRefGenericComponent
显式声明类型。
One time generic factory can make Flow happy一次通用工厂可以让 Flow 开心
/* @flow */
import React from 'react';
type Props<T> = {|
someProp: T
|};
const withRef = <T>() => React.forwardRef<Props<T>, any>((props, ref) => {
return (<div ref={ref} />);
});
const Component = withRef<string>();
Perhaps this example of working code will help future readers on how to use forwardRef with other props in Typescript.也许这个工作代码示例将帮助未来的读者了解如何将 forwardRef 与 Typescript 中的其他道具一起使用。
const FancyInput = forwardRef<HTMLInputElement, InputHTMLAttributes<HTMLInputElement>>(
(otherProps, ref) => (
<input ref={ref} type="text" className="input bg-white py-1 px-2 w-48" {...otherProps} />
),
)
It's not exactly what you're asking for, but there is a work-around.这不完全是你所要求的,但有一个解决方法。 The flow docs about HOCs inspired me. 关于 HOC的流程文档启发了我。 Instead of trying to export a component, export a generic component factory.与其尝试导出组件,不如导出通用组件工厂。 In the file where you want to use the component, create one or more concrete component instances with the factory.在要使用组件的文件中,使用工厂创建一个或多个具体组件实例。
// component definition file
export const createComponent = <T>(): React.AbstractComponent<Props<T>, HTMLElement> =>
React.forwardRef<Props<T>, HTMLElement>((props, ref) => {...});
// file component is used in
import { createComponent } from './definition';
const ComponentT1 = createComponent<T1>();
const SomeComponent = (): MixedElement => {
const ref = useRef();
return <ComponentT1 ref={ref} />
};
The difference from the previous responses is that they use React function components, whereas this uses a plain JavaScript factory, that React doesn't know even existed.与之前的响应不同的是,他们使用 React 函数组件,而这使用了一个普通的 JavaScript 工厂,React 甚至不知道它存在。 It's not a very elegant work-around, but I hope it helps someone out.这不是一个非常优雅的解决方法,但我希望它可以帮助某人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.