Skip to content

ES6-style classes & JSX binding doesn't work as expected. #1436

@jaygarcia

Description

@jaygarcia

This is a fun one :)

I'm in need of class hierarchy and thought that using ES6-style classes would be the best way to achieve this result using basic ES6 OOP patterns. I've got things mostly working, but found that the JSX method binding doesn't actually act as (how I) expected and need someone to help me understand why.

The Breakdown

My class's render function returns a block of components that bind this.onButtonPress. Nothing out of the ordinary.

        return (
             ...
                <View style={styles.controlsContainer}>
                    <MusicControlButton onPress={this.onButtonPress} btnChar={"dislike"} btnStyle={"dislikeButton"} isLikeBtn={true}/>
                    <MusicControlButton onPress={this.onButtonPress} btnChar={"prev"} btnStyle={"prevButton"}/>
                    <MusicControlButton onPress={this.onButtonPress} btnChar={centerBtnChar} btnStyle={centerBtnStyle}/>
                    <MusicControlButton onPress={this.onButtonPress} btnChar={"next"} btnStyle={"nextButton"}/>
                    <MusicControlButton onPress={this.onButtonPress} btnChar={"like"} btnStyle={"likeButton"} isLikeBtn={true}/>
                </View>                     
            </View>
        );

onButtonPress references a map to do method calls. (way cleaner than doing if/else and/or switch/case).

    onButtonPress(buttonType) {
        var methodName = this.methodMap[buttonType];
        this[methodName] && this[methodName]();
    }

The method map is a plain'ol JavaScript object:

(JSX Version)

    methodMap : {
        'prev'  : 'previousTrack',
        'next'  : 'nextTrack',
        'play'  : 'playTrack',
        'pause' : 'pauseTrack'
    },

    onButtonPress : function(buttonType) {
        var methodName = this.methodMap[buttonType];
        this[methodName] && this[methodName]();
    },

-----------
(ES6 version)
AbstractPlayer.prototype.methodMap = {
    prev     : 'previousTrack',
    next     : 'nextTrack',
    play     : 'playTrack',
    pause    : 'pauseTrack',
    like     : 'like',
    dislike  : 'dislike'
};

So here's the rub.

In the JSX Version, the binding works as expected this is a reference to the instance of the class.
es52

In the ES6 version, the binding (this) points to a plain javascript object.
es5

Here's the original class (Using React.createClass()):
https://gist.github.com/jaygarcia/e68682c284ded8e6cea0#file-gistfile1-js-L123

Here's the ES6 version.
https://gist.github.com/jaygarcia/fea5905ee361864aa5d9#file-gistfile1-js-L99

What did I do wrong? I tried to follow the Extensibility guide, but it didn't help much:
https://github.com/facebook/react-native#extensibility

/cc @grgur

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions