假设您有以下组件接受一个或多个子 JSX.Elements 并在使用 React.cloneElement(child, { onCancel: () => {} } 渲染它们时将额外的回调传递给它们的 props/
.
有问题的组件(摘录):
interface XComponentProps {
onCancel: (index: number) => void;
}
class XComponent extends React.Component<XComponentProps> {
render() {
const { onCancel } = this.props;
const children = typeof this.props.children === 'function' ?
React.cloneElement(this.props.children, { onCancel: () => onCancel() }) :
this.props.children.map((child, idx) => (
React.cloneElement(child, { onCancel: () => onCancel(idx) })
));
return <div>{children}</div>;
}
}
有问题的组件(摘录):
interface UserComponentProps { caption: string }
const UserComponent = (props: UserComponentProps) => (
<button onClick={props.onClose}>{props.caption || "close"}</button>
);
ReactDOM.render(
<XComponent onCancel={handleCancel}>
<UserComponent />
<UserComponent />
<UserComponent />
</XComponent>
);
现在 TSC 提示 UserComponent
在其 props 的接口(interface)定义中没有 onCancel
,而实际上确实没有。一种最简单的修复方法是手动将 onCancel
定义到 UserComponentProps
接口(interface)。
但是,我想在不修改子节点的 prop 定义的情况下修复它,以便组件可以接受任意一组 React 元素。在这种情况下,是否有一种方法可以定义返回元素的类型,这些返回元素具有在 XComponent
(父)级别传递的额外隐式 Prop ?
最佳答案
这是不可能的。无法静态地知道 UserComponent 在 ReactDOM.render 上下文中从父 XComponent 接收到什么 Prop 。
如果你想要一个类型安全的解决方案,使用 child 作为函数:
这里是XComponent
定义
interface XComponentProps {
onCancel: (index: number) => void;
childrenAsFunction: (props: { onCancel: (index: number) => void }) => JSX.Element;
}
class XComponent extends React.Component<XComponentProps> {
render() {
const { onCancel } = this.props;
return <div>{childrenAsFunction({ onCancel })}</div>;
}
}
现在您可以使用它来呈现您的 UserComponent
<XComponent onCancel={handleCancel} childrenAsFunction={props =>
<span>
<UserComponent {...props} />
<UserComponent {...props} />
</span>
} />
这会很好地工作,我经常毫无困难地使用这种模式。
您可以重构 XComponentProps 以键入带有相关部分的 childrenAsFunction
Prop (此处为 onCancel
函数)。
关于javascript - 输入一个 React 组件,克隆其子组件以在 TypeScript 中添加额外的 Prop ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41881912/