Modify render function of external React component (with no access)

假如想象 提交于 2019-12-13 04:39:45

问题


I have to use a react component that I cannot modify. It's from an external source, due to changes. This could also be a component from a npm package that I import. This is what it looks like, a simple button:

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>
  );

 }

}

How can I add some functionality with no access to the file (I can create my own component that extends the button)? For example, I want a type prop in there. I thought I can just create a <ButtonExtend onClick={resetState} type="button />.

How can I do this? Ideally I would like to make this even more flexible, so I can also do: <ButtonExtend onClick={resetState} type="submit" name="extended button" />.

I would expect the html to render all the properties from <Button> with my additional html attributes. So I want to use the functionality of the original and my additional props. Or it this not even possible, to change the render method of another component, if the component doesn't make it possible?


回答1:


Although public methods and properties of a component are accessible by refs (https://reactjs.org/docs/refs-and-the-dom.html) the pattern are you looking for is High Order Components (HOC, https://reactjs.org/docs/higher-order-components.html)




回答2:


Unless a component was designed for customization, there is no straightforward way to do this.

Button is an example of badly designed component because it doesn't accept additional props. An issue and PR could be submitted to the repository in order to address original problem.

In extended component, this can be fixed by passing props from extended component.

Parent render result could be modified:

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

If an element that needs to be modified is nested, this may become messy and result in unnecessarily created elements.

A cleaner way is to paste render in extended component and modify it:

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>
  )
 }
}

This way it can be used as

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


来源:https://stackoverflow.com/questions/53087210/modify-render-function-of-external-react-component-with-no-access

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