ffxsam
ffxsam

Reputation: 27713

How to extend a React component?

Let's say there's a React component that I like, but want to modify. For this example, we'll use Material UI's LinearProgress. I want to make a clickable seek bar out of it.

class SeekBar extends LinearProgress {
  componentDidMount() {
    super.componentDidMount();
    console.log('my stuff here');
  }
}

But I feel like I might be very limited as to what I can do as far as changing what render returns. Maybe I'm going about this all wrong, though. If I like a particular React component such as a Material UI component, what is a good, reusable way to customize its look and functionality and make it my own?

Upvotes: 45

Views: 125639

Answers (2)

Inacio Schweller
Inacio Schweller

Reputation: 1986

In the ES6/JSX/React world, you can extend component behaviors and values in many ways. I'd recommend one of the following, considering that you use Material UI.

First case:

You have two components that extend the Component from React:

class ExampleComponent extends React.Component {
  render () {
    return(
      <div>
        <button {...this.props}>
          Click me!
        </button>
      </div>
    )
  }
}

class RenderComponent extends React.Component {
  clickHandler () {
    console.log('Click fired!')
  }

  render () {
    return(
      <ExampleComponent onClick={this.clickHandler.bind(this)} />
    )
  }
}

In that example, onClick is passed via props inside the rendered ExampleComponent. Example here.

Second case:

This is similar on how Material UI extends their own components:

class ExampleComponent extends React.Component {
  clickHandler () {
    console.log('Click fired!')
  }
}

class RenderComponent extends ExampleComponent {
  render () {
    return(
      <div>
        <button onClick={this.clickHandler.bind(this)}>
          Click me!
        </button>
      </div>
    )
  }  
} 

In this example, you have one component that extends Component from React but only has event methods. Then, you extend this component and render your own with the extended behavior. Here is a live example.

Hope it helps!

Upvotes: 71

Tucker
Tucker

Reputation: 588

One way is:

export default class Seekbar extends React.Component{

   // perform any modification

   render(){
      return <LinearProgress ...changes/>
   }
}

Another way is a Higher Order Component, HOC. Here's a great blog with more info: http://natpryce.com/articles/000814.html

I think with Material-UI your best bet would be to wrap it and make any modifications you'd like. Unfortunately this project is very tightly coupled thanks to things like inline styles and their thememanager so taking a single component out may be difficult. HOC would be better for things like sharing some smart functionality across components, like passing a "theme" prop automatically to components.

Upvotes: 4

Related Questions