在与 React 和 TypeScript 中的类型化和 forwardRefs 斗争了一段时间之后,我希望其他人可以为我解决这个问题。
我正在构建一个由三部分组成的 DataList 组件:
ul
li
最终,用法如下所示:
<DataList.List ...>
<DataList.Item ...>content</DataList.Item>
</DataList.List>
为了实现我需要的功能,我利用了 React.forwardRef,但我发现使用 TypeScript 很困难,因为我很难正确键入组件以接收 ref
以及 children
和其他道具.
DataListContainer
我基本上希望这个组件在返回主 DataList 组件(如下所示)时只处理逻辑和事件侦听器。但这里的关键是,我需要在这里创建 DataList ref 并将其分配给返回的组件。
const DataListContainer: React.FC = ({ children }) => {
const listRef = useRef<HTMLUListElement>(null);
return (
<DataList ref={listRef}>{children}</DataList>
);
};
数据列表
我希望 DataList 组件只处理它的 UI 和道具。
interface Props extends TestId {
focusedItemId?: string;
}
const DataList: React.FC<Props> = React.forwardRef<HTMLUListElement, Props>(
({ children, focusedItemId, testId }, ref) => {
return (
<ul
aria-activedescendant={focusedItemId}
data-test-id={testId}
ref={ref}
>
{children}
</ul>
);
},
);
不过,这不太对。由于此设置给了我错误
Type '{ children: any[]; ref: RefObject<HTMLUListElement>; }' is not assignable to type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.
Property 'ref' does not exist on type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.
答案 0 :(得分:1)
你就快到了!在 React TypeScript Cheatsheet 之后,问题出在 DataList
道具上。添加子道具会解决它
interface Props extends TestId {
children?: ReactNode;
focusedItemId?: string;
}
中重新创建了一个简单的示例