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 thisarg parameter provided map, passed callback when invoked, use value. otherwise, value undefined passed use this value. (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])

thisarg

optional. 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

Popular posts from this blog

java - SSE Emitter : Manage timeouts and complete() -

jquery - uncaught exception: DataTables Editor - remote hosting of code not allowed -

java - How to resolve error - package com.squareup.okhttp3 doesn't exist? -