Krešimir Čoko
Krešimir Čoko

Reputation: 115

This scope in a simple React component

Have an issue with, i think, scope when it comes to this.onItemClick in my Filter component.

Getting an error "onItemClick is not defined".

Here's the code for the Filter component.

var Filter = React.createClass({
getDefaultProps() {
    return {
      filterList: [],
      name: ''
    };
},
onItemClick(event) {
    event.currentTarget.style.backgroundColor = '#f00';
},
render() {
    return (
        <div className="filterCloud quarter-section">
            <h3>{this.props.name}</h3>
            <ul>
              {this.props.filterList.map(function(listValue) {
                  return <li onClick={this.onItemClick}>{listValue}</li>;
              })}
              </ul>
        </div>
    )
}});

Upvotes: 3

Views: 2135

Answers (4)

1ven
1ven

Reputation: 7026

If you are using babel, you can use arrow functions:

var Filter = React.createClass({
  getDefaultProps() {
    return {
      filterList: [],
      name: ''
    };
  },
  onItemClick(event) {
    event.currentTarget.style.backgroundColor = '#f00';
  },
  render() {
    return (
      <div className="filterCloud quarter-section">
        <h3>{this.props.name}</h3>
        <ul>
          {this.props.filterList.map((listValue) =>
            <li onClick={this.onItemClick}>{listValue}</li>
          )}
        </ul>
      </div>
    );
  }
});

Upvotes: 0

luiscrjr
luiscrjr

Reputation: 7268

you should bind this to your anonymous function.

Try this:

{this.props.filterList.map(function(listValue) {
                  return <li onClick={this.onItemClick}>{listValue}</li>;
              }.bind(this))}

or use arrow function (automatically does the job):

{this.props.filterList.map( (listValue) => {
       return <li onClick={this.onItemClick}>{listValue}</li>;
   }
)}

Upvotes: 0

Oleksandr T.
Oleksandr T.

Reputation: 77482

You should set this for .map callback, because now this refers to global scope(in browser it is window, or undefined if you use strict mode)

this.props.filterList.map(function(listValue) {
   return <li onClick={this.onItemClick}>{listValue}</li>;
}, this);
   ^^^^^

Upvotes: 1

Piyush.kapoor
Piyush.kapoor

Reputation: 6803

You can use bind here

var Filter = React.createClass({
getDefaultProps() {
    return {
      filterList: [],
      name: ''
    };
},
onItemClick(event) {
    event.currentTarget.style.backgroundColor = '#f00';
},
render() {
    return (
        <div className="filterCloud quarter-section">
            <h3>{this.props.name}</h3>
            <ul>
              {this.props.filterList.map(function(listValue) {
                  return <li onClick={this.onItemClick}>{listValue}</li>;
              }.bind(this))}
              </ul>
        </div>
    )
}});

Upvotes: 0

Related Questions