Handling external function imports

Viewed 101

This might be a rather general question on how to handle imports of external functions and exporting functions.

So I have a component like this:

import React, {Component} from "react";
import {handleChange} from "./path";
//imports from different files...

class Foo extends Component {
    constructor(props) {
        super(props);

        this.bindFunctions();

        this.state = {...};
    };

    //Arrow functions to bind them
    alreadyBound = () => {};

    render() {
        return (
            <div>
                Some text
            </div>
        );
    }

    bindFunctions = () => {
        this.handleChange = handleChange.bind(this);
        //dozens of functions to follow...
    }
}

export default compose(
    translate('translations'),
    connect()
)(Foo);

This is how my external functions look like (They are not part of a component, just files with functions to be reused in various components):

export function handleChange(value, {target: {name, type}}) {
    this.setState({[name]: value});
}

Now this works perfectly fine but it's nauseating. My files grow in size and it's a pain to always bind those functions. I get the necessity of importing the functions/components, but do I really have to bind them in this fashion? Something like arrow functions would be neat and would save me lot of redundant typing. Thanks in advance!

2 Answers

One could import multiple methods at once like this:

import * as path from  "./path";

class Foo { }

Then we can assign them as static methods:

Object.assign( Foo, path );

or as prototype methods:

Object.assign( Foo.prototype, path );

If you want to bind the context its a bit more difficult. That could be done in the constructor:

import * as path from  "./path";

class Foo { 
  constructor(){
    for(var key in path) this[key] = path[key].bind(this);
  }
  //...
}

Or if you just want a few functions to be bound ( maybe faster ) :

import * as path from  "./path";

class Foo { 
  constructor(){
    const bind = ["onClick","onResize" /* whatever*/];
    for(var key of bind) this[key] = this[key].bind(this);
  }
}

Object.assign(Foo, path.prototype);

as an alternative design, you may consider a mixin, eg something like:

let clickable = (superclass) => class extends superclass {  

    constructor(props) { super(props); };

    handleClick = () => { console.log( "clicked ", this ); };
};

class Foo extends clickable(Component) {
    constructor(props) { super(props); this.state = { ... };};

    render() { return <div onClick={this.handleClick}>foobar</div>; }
}   
Related