代码之家  ›  专栏  ›  技术社区  ›  Thijs Koerselman

如何包装组件并继承其props接口

  •  1
  • Thijs Koerselman  · 技术社区  · 7 年前

    我想扩展一个按钮组件并扩展其道具接口类型,以便接受并传递普通按钮拥有的所有道具。在下面的示例中,我创建了一个按钮,该按钮接收来自其onClick函数的承诺,并在等待其解析时显示加载程序。

    我的问题似乎是编译器不知道在哪里可以找到按钮,而且它可能是在自己的命名空间中定义的。

    我能以某种方式将该定义扩展到我自己的组件吗?我不想重新定义像“类型”这样的道具,只需要传递它们。

    import React from 'react';
    import { Button } from 'antd';
    
    // extend interface already defined in antd
    interface ButtonProps {
      onClick: (event: any) => Promise<any>;
    }
    
    interface AsyncButtonState {
      loading: boolean;
    }
    
    export class AsyncButton extends React.Component<
      ButtonProps,
      AsyncButtonState
    > {
      public state = {
        loading: false,
      };
    
      public render() {
        return (
          <Button
            {...this.props}
            onClick={this.handleClick}
            loading={this.state.loading}
          />
        );
      }
    
      private handleClick = async evt => {
        this.setState({ loading: true });
        await this.props.onClick(evt);
        this.setState({ loading: false });
      };
    }
    
    export default AsyncButton;
    

    ----编辑----

    我找到了一种从antd导入ButtonProps界面的方法。现在我只需要想一想如何扩展它。

    import { ButtonProps } from 'antd/lib/button';
    
    interface ButtonProps {
      onClick: (event: any) => Promise<any>;
      children: React.ReactNode;
    }
    

    这为导入提供了一个错误:“导入声明与按钮的本地声明冲突”

    -----再次编辑----

    我过去常常用

    import { Button } from 'antd';
    import { ButtonProps } from 'antd/lib/button';
    
    interface AsyncButtonState {
      loading: boolean;
    }
    
    interface AsyncButtonProps extends ButtonProps {
      onClick: (event: any) => Promise<any>;
      foo?: string;
    }
    

    ... 但现在,ButtonProps似乎不再作为接口导出,而是作为类型导出。现在怎么办?

    3 回复  |  直到 7 年前
        1
  •  3
  •   Thijs Koerselman    7 年前

    毕竟,这很容易。

    import { Button } from 'antd';
    import { ButtonProps } from 'antd/lib/button';
    
    interface AsyncButtonState {
      loading: boolean;
    }
    
    interface AsyncButtonProps extends ButtonProps {
      onClick: (event: any) => Promise<any>;
      foo?: string;
    }
    

    返回承诺的onClick处理程序已经与当前的ButtonProps接口兼容,因此我认为我不需要它。但这显示了添加另一个可选道具,名为 foo .

        2
  •  1
  •   Thijs Koerselman    7 年前

    现在Antd道具导出为type,这似乎是解决它的方法:

    import { Button } from 'antd';
    import { ButtonProps } from 'antd/lib/button';
    
    interface AsyncButtonProps {
      onClick: (event: any) => Promise<any>;
      foo?: string;
    }
    
    export class AsyncButton extends React.Component<
      AsyncButtonProps & ButtonProps,
      AsyncButtonState
    > {
      public render() {
        return (
          <Button
            {...this.props}
            onClick={this.handleClick}
            loading={this.state.loading}
          />
        );
      }
    }
    
        3
  •  0
  •   Yichz    7 年前

    我不熟悉打字,这样行吗?

    interface ButtonProps {
      onClick: (event: any) => Promise<any>;
      ...Button.propTypes
    }
    

    我们对es6做了类似的事情,效果很好

    const propTypes = {
       something: PropTypes.string,
       ...Button.propTypes
    }
    
    MyButton.propTypes = propTypes;