javascript - 输入一个 React 组件,克隆其子组件以在 TypeScript 中添加额外的 Prop

标签 javascript reactjs typescript typescript-typings

假设您有以下组件接受一个或多个子 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/

相关文章:

reactjs - 使用 Electron 锻造打包时如何预编译 typescript

javascript - 将div放入 slider

javascript - TypeScript 中的可选前导参数

javascript - 使用 O(log n) 二进制搜索最接近值的索引/索引

javascript - 基于登录注销和表单提交响应条件渲染

reactjs - useSelector 在初始页面加载时未接收状态,破坏了 Material ui 表

angular - 使用 Angular 4 设置新项目时在 "Promise"中发生冲突

javascript - 如何在 typescript 中指示对象可能没有键

javascript - setInterval 手动设置间隔时间

javascript - 如何在 typescript 中声明成功/失败返回类型