1

I have a problem with my code:

class Note extends React.Component{
  constructor(props){
    super(props);
  }
  xoa(){
    var {index, handleRemove} = this.props;
    handleRemove(index);
  }
  render(){
    return(
      <div>
        <p>{this.props.children}</p>
        <button onClick={this.xoa.bind(this)}> Delete </button>
      </div>
    );
  }
}

class List extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      arrayNote: ['ha', 'hi', 'hu']
    };
  }
  remove(index){
    this.state.arrayNote.splice(index, 1);
    this.setState(this.state);
  }
  render(){
    this.remove = this.remove.bind(this);
    return(
      <div>{this.state.arrayNote.map(function(note, i){
          return (<Note index={i}
            handleRemove={this.remove}
            key={i}>{note}</Note>)
        })}
      </div>
    );
  }
}

ReactDOM.render(
  <List />,
  document.getElementById("root")
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.11.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script>

In console it shows: TypeError: Cannot read property 'remove' of undefined and Uncaught TypeError: Cannot read property 'remove' of undefined Help me resolve this problem, please! Thanks.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Can you give a bit more context? In which line you are getting the error? Although, from your code, I can see that you don't need this line `this.remove = this.remove.bind(this);` – Md Sabbir Alam Feb 28 '20 at 11:32
  • 2
    Can I just say, **thank you** for providing an [mcve] of the problem. That's great!! The problem is described in [this question](http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback) and answered in its answers. Inside your `map` callback, `this` isn't referring to your component instance anymore because you've used a traditional function as the `map` callback. You can fix that by changing the `map` callback to an [arrow function](https://developer.mozilla.org/id/docs/Web/JavaScript/Reference/Functions/Arrow_functions). – T.J. Crowder Feb 28 '20 at 11:35
  • There are a couple of unrelated problems in that code, though: 1. You don't want to call `bind` on every call to `render`. Do it once in your constructor. 2. You're modifying state directly in place in your `remove` call, which is [against the rules](https://reactjs.org/docs/state-and-lifecycle.html#do-not-modify-state-directly). :-) Instead, create a *new* array without the entry you want to remove, and then use `setState` to update `arrayNote` to use that new array. – T.J. Crowder Feb 28 '20 at 11:37
  • 3. You're using the index of the items in `arrayNote` as their `key`. You can't do that if the array may change (as it does in your case). Instead, use some unique identifier on the entries themselves (perhaps make the notes objects with an `id` and `text`) and use that as the `key`. Then you'd pass that same `id` to `remove` (instead of an index) and use `this.setState({arrayNote: this.state.arrayNote.filter(entry => entry.id !== id)});` in `remove`. – T.J. Crowder Feb 28 '20 at 11:39

0 Answers0