Explanation
The problem is that you use Array.prototype.map, which does not bind this unless explicitly told to, and the context of the callback is, in turn, undefined. From the documentation:
If a thisArg parameter is provided to map, it will be passed to callback when invoked, for use as its this value. Otherwise, the value undefined will be passed for use as its this value. (emphasis mine)
Where thisArg is an optional argument of map, see Array.prototype.map Syntax. That means, when you do:
{this.props.questions.map(this.addQuestion)}
this context is undefined when calling this.addQuestion, thus it is undefined in the call to addQuestion. Let me illustrate the problem further by taking a look at your addQuestion method:
addQuestion(question, index) { return ( <div key={index} className="col-xs-12 col-sm-6 col-md-3"> <span onClick={this.askQuestion.bind(this, question)}> {question.q} </span> </div> ); }
Here, since, as mentioned earlier, this is undefined, you are actually trying to do:
undefined.addQuestion.bind(undefined, question)
which throws the error because undefined has no function addQuestion.
Solution
Again, from the documentation:
Syntax
var new_array = arr.map(callback[, thisArg])
thisArg
Optional. Value to use as this when executing callback.
You can see that we can explicitly pass a this context to map, to be used as this context in the callback. That means we can pass an additional argument to be this in the function. This can be applied like so:
{this.props.questions.map(this.addQuestion, this)}
Since this refers to the actual component here, the component is passed as this. That will then correctly call the method addQuestion from the component. An alternative and functionally equivalent way to do is like so:
{this.props.questions.map(this.addQuestion.bind(this))}
Again, since this refers to the actual component here, the component is bound as the this context of the method. That means, in the call to addQuestion, the component is this, like the above solution.
Another thing I'd recommend is that, instead of creating a new function every time with bind, do it once in the constructor:
constructor(/* props if needed */) { /* super(props) if needed */ this.addQuestion = this.addQuestion.bind(this); }
That way, the bound method is already this.addQuestion. You can then get rid of all your bind(this)s, but keep your bind(this, question), as you bind with an argument.