gpt4 book ai didi

reactjs - 如何包装内部组件,保留大部分 Prop ?

转载 作者:行者123 更新时间:2023-12-05 06:18:00 25 4
gpt4 key购买 nike

我想用我自己的 React 功能组件包装一个标准按钮,但我希望新组件的用户能够设置几乎所有底层按钮的 Prop 。当然,我想保持正确的输入,所以如果 WrappedButton 包含一个 button,那么

<WrappedButton formNoValidate={true} onClick={handleClick} />

会正确编译但是

<WrappedButton formNoValidate={5} onKrapnik={handleClick} />

不会,因为 formNoValidate 的类型是 bool 值,而 onKrapnik 不存在。

显然,我不想列出底层组件的合法属性的详尽(且脆弱)列表。

最佳答案

原始组件有一些 Prop 。对于每个 Prop ,你可能想要

  • 原封不动地通过
  • 以某种方式修改
  • 省略
  • 改变它的类型

您可能还想添加一些自己的新 Prop 。举一个简单的案例,你只是想添加一些新的 Prop 。我正在制作一种名为 MultiClick 的新型按钮,它添加了一个可选的 Prop :

type MultiClickProps = {
clickCount?: number;
} & JSX.IntrinsicElements["button"];

const MultiClick: React.FC<MultiClickProps> = ({
clickCount = 2,
...buttonProps
}) => {
// do some stuff
return (
<button {...buttonProps} />
);
};

当然,这不是很有用:如果最终结果是返回一个所有传递的 props 都未修改的按钮,“一些东西”将如何做任何有意义的事情?

所以你可能想要拦截和修改一些 Prop :

const MultiClick: React.FC<MultiClickProps> = ({
clickCount = 2,
onClick,
...buttonProps
}) => {
const handleClick = (
event: React.MouseEvent<HTMLButtonElement, MouseEvent>
) => {
// do some stuff
onClick(event);
};

return (
<button {...buttonProps} onClick={handleClick}/>
);
};

这样,就有机会实际与包装组件的操作进行交互。

现在假设您不喜欢 onClick 的“事件”参数并想用其他东西代替,一个数字。要更改类型,你实际上必须省略旧的 prop 并重新编写它,如下所示:

type MultiClickProps = {
clickCount?: number;
onClick: (n: number) => void;
} & Omit<JSX.IntrinsicElements["button"], 'onClick'>;

可以看到成品代码here .

顺便说一下,所有这一切都依赖于 JSX.IntrinsicElements 的存在,React 的人非常友好地提供了它。假设您正在尝试从某个导出整洁 Prop 类型的库中包装一个功能组件?

幸运的是,您可以为用 Typescript 编写的任何功能组件生成您自己的 props 类型,方法是:

type PropsOf<T> =
T extends React.FunctionComponent<infer U> ? U : never;

如果应用于上面的函数,就像这样:

type MultiClickProps = PropsOf<typeof MultiClick>;

会评估成类似的东西

type MultiClickProps = {
clickCount?: number;
} & React.ClassAttributes<HTMLButtonElement> & React.ButtonHTMLAttributes<HTMLButtonElement>

关于reactjs - 如何包装内部组件,保留大部分 Prop ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61429497/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com