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 providedmap
, passed callback when invoked, use value. otherwise, value undefined passed usethis
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
Post a Comment