The correct way to inherit React components

I understand that my question is a bit biased, but I am very new to Javascript and prototypes , and I read about it, but I really don't understand how to apply these methods to my practical problems. Thus, the example will be very useful. Therefore, I have a React component that basically looks like this:

 var Component1 = React.createClass({ getInitialState: function () { return ({ searchable: true, }) }, function1: function () { return ({ somevalue }) }, render: function () { var redText = { color: 'red' }; var redBorder = { color: 'red', border: '1px solid red' }; return ( <form> <div> <a onClick={this.props.handleAddClick}>Something</a> </div> <div> <label>Some label</label> <input type="text"/> </div> </form> ) }); 

I also have Component2 , which is basically the same, but has another <input/> inside the return its render function.

I also have Component3 that shares the same functions but has a different render() function.

So how to apply inheritance here and avoid copy-paste 3 times? I just skipped some practical illustration, so I would appreciate it.

Edit1 ____________________________________________________ Therefore, I tried to implement Prototype inheritance according to the first answer, but React does not seem to see these functions: getInitialState() is null, the initial state is null after rendering. What is wrong with this approach?

I also tried to go according to the tutorial and did:

 function MyPrototype() {}; MyPrototype.prototype.getInitialState = function () { return ({ someProperty: true; }) }; function Component1() {}; Component1.prototype = Object.create(MyPrototype.prototype); Component1.prototype.render = function () { console.log(this); return (<div></div>)}; var MyComponent1 = React.createClass(new Component1()); 

But when I open the browser, I get an error: Uncaught Invariant Violation: createClass(...): Class specification must implement a render method.

What am I doing wrong like that?

Edit2 _______________________________________________

Actually, I see that React does not support mixins and prototypes. Instead, use a composition. This is explained in this article: Dan Abramov's Mixins article is dead. Long live composition

+4
source share
1 answer

In React, inheritance for components is greatly discouraged .
The reaction is much better for expressing the same relationship through composition.

Here is an example of using composition:

 class Button extends Component { render() { return ( <div className='Button' style={{ color: this.props.color }}> {this.props.children} </div> ) } } class DeleteButton extends Component { render() { return ( <Button color='red'>Delete</Button> ) } } 

Note that DeleteButton uses the look of the Button without inheritance . Instead, Button defines its custom parts through props , and DeleteButton supplies these details. In the actual DOM, both <Button /> and <DeleteButton /> will display the same DOM node - recursive resolution occurs at the render() , and this is the main idea of ​​React.

In fact, if you don't need lifecycle bindings or a local state, you can even define components as functions:

 function Button({ color, children }) { return ( <div className='Button' style={{ color }}> {children} </div> ) } function DeleteButton() { return ( <Button color='red'>Delete</Button> ) } 

You can even mix classes with functions. This would not be possible with inheritance, but works great with composition.

As for your specific use cases:

I also have Component2 , which is basically the same, but has one additional <input/> inside returning its rendering function.

You can use Component1 this.props.children this.props.children and use them in the return value of the render() method and have Component2 render to <Component1><input /></Component> . This is very similar to what I showed above. You also do not need to use children prop - you can pass the React element in any support, for example. <Component1 footer={<input />} /> , and then you can use this.props.footer inside Component1 .

I also have Component3 that shares the same functions but has a different render () function.

If they share any other code (for example, utilities that calculate some data), move this code outside the components into a common module and import it from both components.

If they share any user interface, extract it into another component and use it from both components.

+4
source

All Articles