javascript - React Component's onClick handler not binding to "this" -
i have react component in trying pass span tag onclick event handler. event handler called "askquestion". bind onclick event handler context of component .bind(this, parameter) function.
despite attempt bind "this" i'm still getting error in dev tools console saying "cannot read property askquestion of undefined." i'm pretty sure error means askquestion not bound context of component. need binding askquestion properly.
here component:
class questions extends component { askquestion(question) { alert("hello"); } 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> ); } render() { return ( <div id="questions" classname="row"> <h2>questions</h2> {this.props.questions.map(this.addquestion)} </div> ); } }
explanation
the problem use array.prototype.map, not bind this unless explicitly told to, , context of callback is, in turn, undefined. documentation:
if
thisargparameter providedmap, passed callback when invoked, use value. otherwise, value undefined passed usethisvalue. (emphasis mine)
where thisarg optional argument of map, see array.prototype.map syntax. means, when do:
{this.props.questions.map(this.addquestion)} this context undefined when calling this.addquestion, undefined in call addquestion. let me illustrate problem further taking @ 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, mentioned earlier, this undefined, trying do:
undefined.addquestion.bind(undefined, question) which throws error because undefined has no function addquestion.
solution
again, documentation:
syntax
var new_array = arr.map(callback[, thisarg])
thisargoptional. value use when executing callback.
you can see can explicitly pass this context map, used this context in callback. means can pass additional argument this in function. can applied so:
{this.props.questions.map(this.addquestion, this)} since this refers actual component here, component passed this. correctly call method addquestion component. alternative , functionally equivalent way so:
{this.props.questions.map(this.addquestion.bind(this))} again, since this refers actual component here, component bound this context of method. means, in call addquestion, component this, above solution.
another thing i'd recommend that, instead of creating new function every time bind, once in constructor:
constructor(/* props if needed */) { /* super(props) if needed */ this.addquestion = this.addquestion.bind(this); } that way, bound method this.addquestion. can rid of bind(this)s, keep bind(this, question), bind argument.
Comments
Post a Comment