Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending HTML elements in React and TypeScript while preserving props

I just can't wrap my head around this I guess, I've tried probably half a dozen times and always resort to any... Is there a legitimate way to start with an HTML element, wrap that in a component, and wrap that in another component such that the HTML props pass through everything? Essentially customizing the HTML element? For example, something like:

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/>;     } } 

Usage:

<MyAwesomeButton onClick={...}/> 

Whenever I attempt this sort of composition, I get an error similar to:

Property 'ref' of foo is not assignable to target property.

like image 806
Josh Avatar asked Nov 21 '16 23:11

Josh


People also ask

How do you extend a component in React?

Using the extends keyword, you can allow the current component to access all the component's properties, including the function, and trigger it from the child component. This example creates one component called ParentClass. jsx. ParentClass extends the component from React as React.

Why do we Extends component in React?

Extending Component will give you access to functions like componentDidMount , componentDidUpdate , componentWillUnmount and render . Show activity on this post. if you extend React. Component class , you can use the life cycle of the Component which can be used for mounting and unmounting.

Can React component modify props?

A component cannot update its own props unless they are arrays or objects (having a component update its own props even if possible is an anti-pattern), but can update its state and the props of its children.

Can props pass JSX?

Not only can JSX elements be passed as props to components, but we can also pass other components as props.


2 Answers

You can change the definition of your component to allow the react html button props

class MyButton extends React.Component<MyButtonProps & React.HTMLProps<HTMLButtonElement>, {}> {     render() {         return <button {...this.props}/>;     } } 

That will tell the typescript compiler that you want to enter the button props along with 'MyButtonProps'

like image 167
Jordan Upham Avatar answered Sep 24 '22 04:09

Jordan Upham


Seems Like the above answer is outdated.

In my case I'm wrapping a styled component with a functional component, but still want to expose regular HTML button properties.

export const Button: React.FC<ButtonProps &   React.HTMLProps<HTMLButtonElement>> = ({   ...props,   children,   icon }) => (   <StyledButton {...props}>     {icon && <i className="material-icons">{icon}</i>}     {children}   </StyledButton> ); 
like image 35
EimerReis Avatar answered Sep 20 '22 04:09

EimerReis