我只是无法绕过这个我想,我已经尝试了大约六次,总是诉诸any
...是否有合法的方式开始HTML元素,将其包装在组件中,并将其包装在另一个组件中,以便HTML props传递所有内容?基本上自定义HTML元素?例如,像:
interface MyButtonProps extends React.HTMLProps<HTMLButtonElement> {}
class MyButton extends React.Component<MyButtonProps, {}> {
render() {
return <button/>;
}
}
interface MyAwesomeButtonProps extends MyButtonProps {}
class MyAwesomeButton extends React.Component<MyAwesomeButtonProps, {}> {
render() {
return <MyButton/>;
}
}
用法:
<MyAwesomeButton onClick={...}/>
每当我尝试这种组合时,我都会收到类似于:
的错误财产&#39; ref&#39; foo不能分配给目标财产。
答案 0 :(得分:22)
您可以更改组件的定义以允许反应html按钮道具
class MyButton extends React.Component<MyButtonProps & React.HTMLProps<HTMLButtonElement>, {}> {
render() {
return <button {...this.props}/>;
}
}
这将告诉typescript编译器你想要输入按钮道具以及'MyButtonProps'
答案 1 :(得分:22)
似乎上面的答案已经过时了。
在我的案例中,我将样式化的组件与功能性组件包装在一起,但仍然希望公开常规的HTML按钮属性。
export const Button: React.FC<ButtonProps & React.ButtonHTMLAttributes<HTMLButtonElement>> = ({ children, icon, ...props}) => (
<StyledButton { ...props}>
{ icon && (<i className = "material-icons" >{icon}< /i>)}
{children}
</StyledButton>);
答案 2 :(得分:13)
我总是喜欢这样:
import React from 'react';
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
title: string;
showIcon: boolean;
}
const Button: React.FC<ButtonProps> = ({ title, showIcon, ...props }) => {
return (
<button {...props}>
{title}
{showIcon && <Icon/>}
</button>
);
};
然后您可以做:
<Button
title="Click me"
onClick={() => {}} {/* You have access to the <button/> props */}
/>
答案 3 :(得分:1)
private yourMethod(event: React.MouseEvent<HTMLButtonElement>): void {
event.currentTarget.disabled = true;
}
<Button
onClick={(event) => this.yourMethod(event)}
/>
答案 4 :(得分:1)
我今天遇到了同样的问题,这是我如何解决的问题:
ReactButtonProps.ts
import {
ButtonHTMLAttributes,
DetailedHTMLProps,
} from 'react';
/**
* React HTML "Button" element properties.
* Meant to be a helper when using custom buttons that should inherit native "<button>" properties.
*
* @example type MyButtonProps = {
* transparent?: boolean;
* } & ReactButtonProps;
*/
export type ReactButtonProps = DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;
在Button-ish
组件中的用法:
import classnames from 'classnames';
import React, { ReactNode } from 'react';
import { ReactButtonProps } from '../../types/react/ReactButtonProps';
type Props = {
children: ReactNode;
className?: string;
mode?: BtnMode;
transparent?: boolean;
} & ReactButtonProps;
const BtnCTA: React.FunctionComponent<Props> = (props: Props): JSX.Element => {
const { children, className, mode = 'primary' as BtnMode, transparent, ...rest } = props;
// Custom stuff with props
return (
<button
{...rest} // This forward all given props (e.g: onClick)
className={classnames('btn-cta', className)}
>
{children}
</button>
);
};
export default BtnCTA;
用法:
<BtnCTA className={'test'} onClick={() => console.log('click')}>
<FontAwesomeIcon icon="arrow-right" />
{modChatbot?.homeButtonLabel}
</BtnCTA>
我现在可以使用onClick
,因为由于它是从ReactButtonProps扩展而被允许的,并且它通过...rest
自动转发到DOM。
答案 5 :(得分:1)
我为我解决了这段代码,您只需要从react导入ButtonHTMLAttributes
就可以了
import { ButtonHTMLAttributes } from "react";
interface MyButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
children: any;
}
export const MyButton = (props: ButtonI) => {
const { children } = props;
return <button {...props}>{children}</button>;
};
答案 6 :(得分:1)
这就是我在扩展原生元素时所做的:
import React, { ButtonHTMLAttributes, forwardRef } from "react";
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
myExtraProp1: string;
myExtraProp2: string;
}
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ myExtraProp1, myExtraProp2, ...props }, ref) => (
<button
{...props}
ref={ref}
// Do something with the extra props
/>
),
);
Button.displayName = "Button";
forwardRef
确保您在使用组件时可以通过 ref
获得对底层 HTML 元素的引用。
答案 7 :(得分:0)
您可以这样做以扩展按钮属性
import { ButtonHTMLAttributes, ReactNode } from "react";
interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
children: ReactNode;
}
const Button = ({ children, ...props }: Props): JSX.Element => {
return <button {...props}>{children}</button>;
};