I have the following TS React component (MyButton.tsx):
import React from 'react'
interface MyButtonProps {
children: JSX.Element | JSX.Element[],
className?: string,
variant?: 'big-button' | 'medium-button' | 'small-button'
}
const MyButton = ({
children,
className,
variant
}: MyButtonProps) => {
let baseClassName: string = 'my-button'
if (variant != null) {
baseClassName = ' ' variant
}
return (
<button
className={baseClassName ' ' className}
>
{children}
</button>
)
}
export default MyButton
It's a fairly simple component to understand. I can use it in the following way:
<MyButton variant='big-button'>Click Here</MyButton>
It works fine. However, ideally I would like to pass in props to this component that are not defined in the Interface for the MyButtonProps
. For example, I would like to be able to do something like the following:
<MyButton variant='small-button' type="reset" disabled>Reset Form</MyButton>
The type
and disabled
props are normal HTML attributes, but TS throws an error at me because I have not defined them in the Interface. How can I solve this? I remember seeing the ...
operator for a use case similar to this, but can't find it anymore. Any help is greatly appreciated!
CodePudding user response:
Try this:
interface MyButtonProps extends React.HTMLProps<HTMLButtonElement> {
children: JSX.Element | JSX.Element[],
className?: string,
variant?: 'big-button' | 'medium-button' | 'small-button'
}
Try this:
const MyButton = (
children: JSX.Element | JSX.Element[],
className?: string,
variant?: 'big-button' | 'medium-button' | 'small-button',
...others: any[]
)
const MyButton = ({
children,
className,
variant,
...props
}: MyButtonProps) => {
let baseClassName: string = 'my-button'
if (variant != null) {
baseClassName = ' ' variant
}
return (
<button
className={baseClassName ' ' className}
{ ...props }
>
{children}
</button>
)
}
CodePudding user response:
Try this:
const MyButton = (
children: JSX.Element | JSX.Element[],
className?: string,
variant?: 'big-button' | 'medium-button' | 'small-button',
...others: any[]
)
So this should work:
const MyButton = (
children: JSX.Element | JSX.Element[],
className?: string,
variant?: 'big-button' | 'medium-button' | 'small-button',
...others: any[]
) => {
let baseClassName: string = 'my-button'
if (variant != null) {
baseClassName = ' ' variant
}
return (
<button {...others}
className={baseClassName ' ' className}
>
{children}
</button>
)
}
export default MyButton
Now you can use those extra props by simply spreading them in jsx element like this <button {...others}/>
.
Example:
<MyButton className="blah" disabled/>
The above disabled
will be applied to <button/>
as follows:
<button disabled/>