问题
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