0

I have bound the removeNote function in the constructor, but I still get the cannot read property error.

 class Wall extends React.Component {
        constructor(props) {
            super(props);
            this.state = {
                noteDataArray: ['Note value 1 yay','2 notes']
            };
            this.removeNote = this.removeNote.bind(this);
        }

        saveNote(value, index) {
            var temp = this.state.noteDataArray;
            temp[index] = value;
            this.setState({noteDataArray: temp});
        }

        removeNote(index) {
            var temp = this.state.noteDataArray;
            temp.splice(index, 1);
            this.setState({noteDataArray: temp});
        }

        render() {
            return (
                    <div className="Wall">
                        {this.state.noteDataArray.map(function (value, index) {
                            return (
                                    <Notes key={index} index={index} removeit={this.removeNote} >
                                        {value}
                                    </Notes>
                            );
                        })}
                    </div>
            )
        }
    }

When I use the same binding method in another component , it works.

Malcolm Vaz
  • 131
  • 5
  • http://stackoverflow.com/a/40639996/2902660 – Pineda Apr 15 '17 at 23:18
  • Also keep in mind that state is async, and using it to calculate new state can lead to inconsistency. So to be sure you're having up-to-date date, you should use it like: `this.setState((prevState) => { var temp = prevState.noteDataArray; temp[index] = value; return { noteDataArray: temp } })` (more details: https://facebook.github.io/react/docs/react-component.html#setstate) – Koen. Apr 15 '17 at 23:24

2 Answers2

1

Try using an arrow function when you are mapping through this.state.noteDataArray like so:

{this.state.noteDataArray.map((value, index) => {
                        return (
                                <Notes key={index} index={index} removeit={this.removeNote} >
                                    {value}
                                </Notes>
                        );
                    })}

Have a look in the MDN article about arrow functions

Until arrow functions, every new function defined its own this value... This proved to be annoying with an object-oriented style of programming.

An arrow function does not create its own this context, so this has its original meaning from the enclosing context

Community
  • 1
  • 1
Piotr Berebecki
  • 7,428
  • 4
  • 33
  • 42
1

You may have bound this.remove but you call it within Array#map which creates its own this context within each iteration of its callback.

Array#map takes a second argument that will be used as this within each iteration.

Amending your code as follows should do the trick:

this.state.noteDataArray.map(function (value, index) {
  return (
    <Notes key={index} index={index} removeit={this.removeNote} >
      {value}
    </Notes>
  );
}, this);
//    ^---- add this as second argument 
Pineda
  • 7,435
  • 3
  • 30
  • 45