修改外部React组件的渲染功能(无访问权限)

时间:2018-10-31 15:41:18

标签: javascript reactjs composition

我必须使用无法修改的react组件。由于更改,它来自外部来源。这也可能是我导入的npm包中的组件。这就是它的样子,一个简单的按钮:

class Button extends React.Component {

 // ... more code above  
 render() {
  const { onClick, disabled, children} = this.props;

  return (
    <button className={this.getClasses()} onClick={onClick} disabled={disabled}>
      {this.props.symbol && <Icon symbol={this.props.symbol} />}
      {children}
    </button>
  );

 }

}

如何添加一些无法访问文件的功能(我可以创建自己的扩展按钮的组件)?例如,我想要一个type道具。我以为我可以创建一个<ButtonExtend onClick={resetState} type="button />

我该怎么做?理想情况下,我想使其更加灵活,因此我也可以这样做:<ButtonExtend onClick={resetState} type="submit" name="extended button" />

我希望html用我的其他html属性呈现<Button>的所有属性。所以我想使用原始功能和其他道具。还是如果该组件无法实现,则甚至无法更改另一个组件的渲染方法?

2 个答案:

答案 0 :(得分:0)

除非组件是为定制而设计的,否则没有简单的方法可以做到这一点。

Button是组件设计不良的一个示例,因为它不接受其他道具。可以将问题和PR提交到资源库中,以解决原始问题。

在扩展组件中,可以通过传递扩展组件中的道具来解决此问题。

父母render的结果可以修改:

class ButtonExtend extends Button {
 // ... more code above  
 render() {
  const button = super.render();
  const { symbol, children, ...props } = this.props;

  return React.cloneElement(button, {
    children: [
      symbol && <Icon symbol={symbol} />,
      ...children
    ],
    ...props
  });
}

如果嵌套了需要修改的元素,则可能会变得凌乱,并导致不必要地创建元素。

一种更干净的方法是将render粘贴到扩展组件中并对其进行修改:

class ButtonExtend extends Button {
 // ... more code above  
 render() {
  const { symbol, children, ...props } = this.props;

  return (
    <button className={this.getClasses()} {...props}/>
      {symbol && <Icon symbol={symbol} />}
      {children}
    </button>
  )
 }
}

这种方式可以用作

<ButtonExtend onClick={resetState} type="submit" name="extended button" />

答案 1 :(得分:0)

尽管refshttps://reactjs.org/docs/refs-and-the-dom.html)可以访问组件的公共方法和属性,但您正在寻找的模式是高阶组件(HOC,https://reactjs.org/docs/higher-order-components.html