How do I extend react-bootstrap component using typescript?

若如初见. 提交于 2021-01-27 12:26:43

问题


I am using react-bootstrap@1.0.0-beta.14 and I am trying to create a custom Button component using react-bootstraps Button, adding another prop, isLoading. Because of the way react-bootstrap types are defined I ended up importing some helpers types and copying a part of react-bootstrap types:

import React from 'react'
import { Button as Btn, ButtonProps } from 'react-bootstrap'
import { BsPrefixProps, ReplaceProps } from 'react-bootstrap/helpers'

interface Props {
  isLoading?: boolean
}

type BtnProps<As extends React.ElementType = 'button'> = ReplaceProps<
  As,
  BsPrefixProps<As> & ButtonProps
>

export const Button: React.FC<BtnProps & Props> = ({ isLoading, disabled, ...props }) => {
  return <Btn {...props} disabled={isLoading || disabled} />
}

This almost works. The error I got is telling me that ref prop types are wrong:

Types of property 'ref' are incompatible.

...

Type '(instance: HTMLButtonElement | null) => void' is not assignable to type '(instance: Button> | null) => void'.

I stripped most of the error message to get the relevant bit. Do I need to wrap the component in forwardRef for this work?


回答1:


you can see better way of doing is at following code piece.

import React from 'react';
import { Button, ButtonProps } from 'react-bootstrap'

interface PropType extends ButtonProps {
    buttonText: string;
    isSubmitting: boolean;
}

export const SubmitButton: React.FC<PropType> = (props: PropType) => {
let { isSubmitting, buttonText, ...remainingProps } = props;
    return (
        <Button  variant="primary" type="submit" disabled={props.isSubmitting} style={{margin: 10}} {...remainingProps}>
            {props.buttonText}
        </Button>
    )
}



回答2:


I am just wondering if the following simplification would not suffice?

import React from 'react'
import { Button as Btn, ButtonProps } from 'react-bootstrap'

interface Props {
  isLoading?: boolean
}

export const Button: React.FC<ButtonProps & Props> = ({ isLoading, ...props }) => {
  return <Btn {...props} disabled={isLoading || props.disabled} />
}



回答3:


So, I decided to solve this with a workaround:

export const Button: React.FC<Props & React.ButtonHTMLAttributes<HTMLButtonElement>> = 
({ isLoading, disabled, ...props }) => 
<Btn disabled={isLoading || props.disabled} {...props} />

This is not ideal because in theory, Btn can be a different native element (not always a button) but it's good enough for my use case.



来源:https://stackoverflow.com/questions/60297772/how-do-i-extend-react-bootstrap-component-using-typescript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!