我们正在使用typescript开发一个内部react库,它有一个组件,这里称为Parent,我们希望能够接收一个自定义组件作为要渲染的 prop ,但也可以从Parent调用子组件函数。为此,我们使用forwardRef和useImperativeHandle。为了确保所有作为props传入的组件都具有正确的功能,我们有一个名为CustomFormProps的接口,如下所示:
export interface CustomFormProps<T> {
getValue: () => T | null;
reset: () => void;
}
Parent组件的属性类型为ParentProps。
export interface ParentProps<T> {
CustomFilterFormComponent?: React.ComponentType<
CustomFormProps<T> & React.RefAttributes<T>
>;
}
Parent相对简单,呈现一个div、自定义组件和一个触发自定义组件中函数的按钮。
const Parent = <T extends object>({
CustomFilterFormComponent
}: ParentProps<T>) => {
const customFormRef = useRef<any>(null);
const customFormProps: any = {
ref: customFormRef
};
const handleReset = () => {
if (customFormRef.current) {
customFormRef.current.reset();
}
};
return (
<div>
<div>Hello</div>
{CustomFilterFormComponent && (
<CustomFilterFormComponent {...customFormProps} />
)}
<button onClick={handleReset}>Reset</button>
</div>
);
};
我有一个传递给Parent的示例组件。代码工作正常,但是在我们将CustomFilterFormComponent传递给Parent的那一行,我们得到了这个错误:
类型“ForwardRefExoticComponent<CustomFilterFormFilters & RefAttributes>"不能分配给类型”ForwardRefExoticType <CustomFormProps & RefAttributes>“|未定义'。类型“ForwardRefExoticComponent<CustomFilterFormFilters & RefAttributes>"不能分配给类型”FunctionComponent<CustomFormProps & RefAttributes“。参数”props“和”props“的类型不兼容。类型“CustomFormProps & RefAttributes "不可分配给类型”CustomFilterFormFilters & RefAttributes“。类型”CustomFormProps & RefAttributes“中缺少属性”upcs“,但类型”CustomFilterFormFilters“中需要该属性。
这里是一个链接到一个codesandbox,我能够重现错误:https://codesandbox.io/s/loving-kapitsa-ysn9g7?file=/src/App.tsx
这里是完整的源代码:
import { useImperativeHandle, useRef, useState } from "react";
import "./styles.css";
import React from "react";
export interface CustomFormProps<T> {
getValue: () => T | null;
reset: () => void;
}
export interface ParentProps<T> {
CustomFilterFormComponent?: React.ComponentType<
CustomFormProps<T> & React.RefAttributes<T>
>;
}
interface CustomFilterFormFilters {
upcs: number[];
}
const YourCustomFilterFormComponent = React.forwardRef<
CustomFormProps<CustomFilterFormFilters>,
CustomFilterFormFilters
>(
(
props: CustomFilterFormFilters,
ref: React.Ref<CustomFormProps<CustomFilterFormFilters>>
) => {
const [upcs, setUpcs] = useState<any[]>(props.upcs ?? []);
const upcOptions = [12345, 56789, 98635];
const getValue = (): CustomFilterFormFilters | null => {
if (upcs.length > 0) {
return { upcs } as CustomFilterFormFilters;
}
return null;
};
useImperativeHandle(ref, () => ({
getValue,
reset: () => {
setUpcs([]);
}
}));
const handleSelection = (upc: number, selected: boolean) => {
if (selected) {
if (upcs.indexOf(upc) === -1) setUpcs([...upcs, upc]);
} else {
setUpcs(upcs.filter((q) => q != upc));
}
};
return (
<div>
{upcOptions.map((upc, idx) => (
<div key={idx}>
<input
type="checkbox"
id={`chkCustomFilterForm-${idx}`}
checked={upcs.indexOf(upc) > -1}
onChange={(evt) => {
handleSelection(upc, evt.target.checked);
}}
/>
<label htmlFor={`chkCustomFilterForm-${idx}`}>{upc}</label>
</div>
))}
</div>
);
}
);
const Parent = <T extends object>({
CustomFilterFormComponent
}: ParentProps<T>) => {
const customFormRef = useRef<any>(null);
const customFormProps: any = {
ref: customFormRef
};
const handleReset = () => {
if (customFormRef.current) {
customFormRef.current.reset();
}
};
return (
<div>
<div>Hello</div>
{CustomFilterFormComponent && (
<CustomFilterFormComponent {...customFormProps} />
)}
<button onClick={handleReset}>Reset</button>
</div>
);
};
export default function App() {
return (
<div className="App">
<Parent CustomFilterFormComponent={YourCustomFilterFormComponent} />
</div>
);
}
任何帮助都非常感谢。谢谢你,谢谢!
1条答案
按热度按时间jyztefdp1#
看起来
ParentProps
与React.ComponentType
的期望值和React.forwardRef
对YourCustomFilterFormComponent
的定义不匹配。如何修改
ParentProps
:警告消失后,似乎仍按预期工作。https://codesandbox.io/s/amazing-matan-p8cwwc
ParentProps
的这个新定义可以在您提供的可复制示例中工作,但是如果您的代码库的其他部分不适用,请更新您的问题,说明此类型定义需要涵盖的范围。