1

I try to define some steps ( I call them pages ) in an array and each page should have the possibility to call a function on enter.

My page definition is within an array of pages and the nextHandler ( custom method ) sets the current page index and tries to call the defined function. My React class looks ( abbreviated ) like this:

var App = React.createClass({
    pageDefinitions: [
        {
            title: "Page 1",
            enterFunction: this.enterPageOne
        }
    ],

    enterPageOne: function() {
        console.log("Something useful here");
    },

    nextHandler: function() {
        var st = this.getState();
        st.currentPageIndex = st.currentPageIndex + 1;
        this.setState(st);
        var page = this.pageDefinitions[this.state.currentPageIndex];
        console.log(typeof page.enterFunction);
        console.log(page.title);
        if ( typeof page.enterFunction === "function") {
            page.enterFunction();
        }
    },

    getInitialState: function() {
        return {
            currentPageIndex = -1
        };
    },

    render: function() {
        return (
            <div>Left out</div>
    }
});

While title correctly prints out on console, the function is always undefined. How can I provide a function reference in my array?

Edit: As @gillesc and @justin-morgan pointed out it is a problem of scope ( this is pageDefinition, not the class )

Edit 2: Found solution, I changed pageDefinitions to getPageDefinitions() like this:

getPageDefinitions: funtion() {
    var self = this;
    return [
        {
            title: "Page 1",
            enterFunction: selfenterPageOne
        }
    ];
}
1
  • 1
    pageDefinitions is an array of object, so this in the first object would reference to the object inside the array and not your main object. So basically this.enterPageOne is undefined. Commented Jun 7, 2015 at 12:47

3 Answers 3

1

this.enterPageOne is undefined because this isn't bound to what you think it is. Try this:

var enterPageOne = function() {
    console.log("Something useful here");
};

var App = React.createClass({
    pageDefinitions: [
        {
            title: "Page 1",
            enterFunction: enterPageOne
        }
    ],
    //...etc.
Sign up to request clarification or add additional context in comments.

7 Comments

Now I get an error at line 5 enterFunction: context.enterPageOne: Uncaught TypeError: Cannot read property 'enterPageOne' of undefined
@Sascha - I can't believe I just did that. My context object would also be undefined at that point. Try it now.
this works, but the function needs to have access to the state property of the App class, so I just move the problem this way
@Sascha - That sounds like an unrelated problem, because now we're talking about the context of enterPageOne while it's running. I don't know much about React, but if it binds this to a context while running enterPageOne, and if the state property becomes part of that context, you should be able to access it just fine. Hope that makes sense.
Unfortunately, state seems to be added by the React.createClass call, and the initial state can be provided be the getInitialState method that I left in the sample code. Moving the method out of the context of React.createClass removes access to the state method. You can have multiple React classes the do not share the state.
|
0

if you don't want a global function outside of App component, you can try this. It's not catchy but you can manage it in scope.

 nextHandler: function() {
    ...
    var page = this.pageDefinitions[this.state.currentPageIndex];
    //register enterPageOne function into the array
    page.enterFunction = this.enterOnePage;
    console.log(typeof page.enterFunction);
    console.log(page.title);
    if ( typeof page.enterFunction === "function") {
        page.enterFunction();
    }
},

1 Comment

Taking your approach I just could call the function directly, or do I miss a point?
0

Do not define an array on class level but a function that returns an array:

getPageDefinitions: funtion() {
    var self = this;
    return [
        {
            title: "Page 1",
            enterFunction: selfenterPageOne
        }
    ];
}

Please note: As a downside , this will create every time a new array when called. This should be considered

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.