Skip to content Skip to sidebar Skip to footer

In React Is There A More Standard Way Than This Of Referring To The Outer Class From Within A Map?

I'm so sorry for how badly worded that title is but I'm just learning React and I got something working in what feels like a bit of a hacky way, and I'm trying to figure it out pro

Solution 1:

This is called context binding, you need to bind the proper context otherwise this keyword (points to react component) will not be available inside map. You can write it like these way:

1. By using arrow function:

{   
    this.state.listItems.map( (item,index) => {
        return (
            <ListItemid={index}key={index}title={item}removeItem={this.removeItem.bind(this)} />
        );
    })
}

2. By using .bind(this) with callback method:

{   
    this.state.listItems.map( function(item,index) {
        return (
            <ListItemid={index}key={index}title={item}removeItem={this.removeItem.bind(this)} />
        );
    }.bind(this))
}

Suggestion: Instead of binding the events inside render method, you should bind them in the constructor, it will avoid the creation of new function during the re-rendering.

Reference: https://stackoverflow.com/a/31296221/5185595

For more detail on arrow function check this answer: https://stackoverflow.com/a/34361380/5185595

Solution 2:

You're mostly correct. However the word you're looking for is "context", not "scope".

Scope is how visible a variable declaration is to other code. A variable is either in the global scope, or it's scoped locally to the function in which it was called.

Context deals specifically with the value of the keyword this. this refers to the object that the function was called within. In React, since all of the functions are called from within the Component object, the value of this is typically the Component itself.

On to your workaround to the problem - it's perfectly valid and is in fact used quite often by developers. You'll often see something like var self = this so that the original value of this can easily be retained.

However, if you're coding in ES6 or using Babel or some other transpiler, you can use the ES6 "arrow function":

render() {
    return (
      <divclassName="App"><AddItemaddItem={this.addItem.bind(this)} /><ul>
          {this.state.listItems.map((item,index) => {
              return (
                  <ListItemid={index}key={index}title={item}removeItem={this.removeItem.bind(this)} />
              );
          })}
        </ul></div>
    );
  }

The "arrow function" does not bind a new value for this despite being a new function call. Instead it uses the this value of the context it was called in. It's very handy for situations like this; myself and other developers use it all the time, so it's quite in style.

Solution 3:

you want to keep the class context inside your map function. To make things more performant you should use a function that is pre-bound to the class in the return of your map.

removeItem = () => {
    ...
}
listItem = (item, index) => {
    return (
        <ListItemid={index}key={index}title={item}removeItem={this.removeItem} />
    );
}
getListItems = () => {
    returnthis.state.listItems.map((item,index) =>this.listItem(item, index))
}
render() {
    const elems = this.getListItems();
    return (
      <divclassName="App"><AddItemaddItem={this.addItem.bind(this)} /><ul>
          {elems}
        </ul></div>
    );
  }

notice I use an arrow function on your class methods. this way each of those methods are pre-bound. you no longer need to call .bind(this) everywhere and its more performant

The arrow inline binding is available if you have enabled stage-2 or transform-class-properties in babel. If you haven't you can pre bind your functions in the constructor so that binding only needs to happen once.

constructor() {
    super();
    ...
    this.removeItem = this.removeItem.bind(this);
    this.listItem = this.listItem.bind(this);
    this.getListItems = this.getListItems.bind(this);
}

Post a Comment for "In React Is There A More Standard Way Than This Of Referring To The Outer Class From Within A Map?"