如何避免对通过React.children.map注入到我直接在打字稿中呈现的组件的道具进行类型检查?
type ContainerProps = {
children: JSX.Element[];
};
export const Container: React.FC<ContainerProps> = ({ children }) => {
const [isOpen, setIsOpen] = useState<boolean>(false);
return (
<React.Fragment>
{React.Children.map(children, child =>
React.cloneElement(child, {
isOpen,
setIsOpen
})
)}
</React.Fragment>
);
};
type ClickProps = {
children: React.ReactNode;
isOpen: boolean;
setIsOpen: (boolean) => void;
};
export const Click: React.FC<ClickProps> = ({ children, isOpen, setIsOpen }) => {
return (
<div onClick={() => setIsOpen(!isOpen)}>
{children}
</div>
);
};
在这种情况下,当我调用以下代码时,由于未传递isOpen
和setIsOpen
道具,因此出现以下错误。我如何在Click组件内具有这些道具的类型安全性?直接调用click组件时不需要传递它们吗?
<Container>
<Click>
<h1>Test</h1>
</Click>
</Container>
ERROR
Type '{ children: Element; }' is missing the following properties from type 'ClickProps': isOpen, setIsOpents(2739)
答案 0 :(得分:1)
如何在Click组件内部具有这些道具的类型安全性,而在直接调用click组件时无需传递它们呢?
这里的问题是当您这样做时:
<Click>
<h1>Test</h1>
</Click>
您实际上是在渲染该组件,将其转换为JSX片段。稍后将其克隆,但这对于此初始渲染无关紧要。而且此组件具有一些必需的道具:isOpen
和setIsOpen
。
这就像调用缺少参数的函数一样。调用无效。
我认为使用此设置的最佳方法是使道具成为可选,然后除非提供了道具,否则就保释。
type ClickProps = {
children: React.ReactNode;
isOpen?: boolean;
setIsOpen?: (isOpen: boolean) => void;
};
export const Click: React.FC<ClickProps> = ({ children, isOpen, setIsOpen }) => {
if (isOpen === undefined || setIsOpen === undefined) return null
return (
<div onClick={() => setIsOpen(!isOpen)}>
{children}
</div>
);
};
这样,在没有道具的情况下渲染组件是有效的调用。
不过,我不太确定如何使用React.cloneElement
获得类型安全。将子级转换为JSX.Element[]
后,打字稿将不再知道来自哪个原始组件,因此我不确定它如何知道要执行哪些道具。
我不确定您要在这里做什么,但是我会在这里重新考虑您的整体策略,看看您是否可以不用React.cloneElement
来做到这一点。