Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React ES6 alternative for mixins

I'm looking for an alternative to React mixins when using ES6 classes.

I would like to inject some functions into my react components, but those functions need React elements.

React ES5 used mixins for that, but React Classes don't support mixins. What's the alternative to mixins in React classes?

like image 811
Jan Kowalski Avatar asked Jan 30 '16 15:01

Jan Kowalski


3 Answers

Mixins won't be supported by React in the future. Instead of them you should use Higher-order Components. This gist provides great explanation of this concept.

Instead of mixing extra functionality into your component you should create a separate one which will provide this functionality to another components.

class MyComponent extends React.component {
    render() {
        //...
    }
}

export default extraFunctionality(MyComponent);

If you're using Babel with ES7 plugin you can use decorator syntax for that:

@extraFunctionality
class MyComponent extends React.component {
    render() {
        //...
    }
}
like image 174
Valery Bugakov Avatar answered Oct 16 '22 17:10

Valery Bugakov


Remember, MyComponent, a JS class, is just syntactic sugar, cause under the hood will be used as a function constructor, so with that in mind a simple trick would be something like:

var MyMixin = require('whatever/path');
class MyComponent extends React.Component{
    constructor(props){
        super(props);
        MyMixin.call(this); //this line adds the methods
        this.state = {message: 'Hello world'};
    }
    render(){
        return (
            <div>{this.state.message}</div>
        );
    }
}

Then your Mixin module has to export a function with your mixin functions

module.exports = function(){
    var self = this;
    this.method1 = function(){
        // do stuff
        self.setState({
            message: "hello again"
        });
    }
    this.method2 = function(){
        // do more stuff
    }
}
like image 44
danielmeneses Avatar answered Oct 16 '22 17:10

danielmeneses


You can use an anonymous function to wrap one or multiple classes around the React.Component class to add extra functionality:

First create the wrapper class with the extras:

compExtras.jsx

export default superClass => class extends superClass {

  constructor(props) {  // take props from 'MyComp'.
    super(props);
    this.foo = 'some value';
    this.someChildProp = props.bar; // You can use props of 'MyComp'.
  }

  someExtraMethod(x) {
    return [x, this.foo, this.childProp];
  }
};

Now create a usual component that extends the React.Component with your extras-class to inject the extra functionality:

myComp.jsx

import extras from './compExtras.js';

class MyComp extends extras(React.Component) {  // extend 'React.Component' with 'extras'

  constructor(props) {
    super(props);  // Pass props to the 'extras' class.
    this.qux = 'some value';
  }

  render() {
    console.log(this.someExtraMethod('foo'));  // You have access to that method.
    return <div></div>;
  }
}

If you want to use multiple extensions for a component create your component like this:

class MyComp extends extrasOne(extrasTwo(React.Component)) {

Just make sure each extras-class passes props to its parent class with super(props), so every class gets access to props.

like image 32
Rotareti Avatar answered Oct 16 '22 16:10

Rotareti