Search code examples
reactjsreact-dom

Trouble with binding event handlers in react


  1. What am I doing wrong, specifically when I click the button it gives me: Uncaught TypeError: Cannot read property 'onDismiss' of undefined

  2. When is it necessary to bind an event handler to the constructor function?

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import contacts from './contacts';


class App extends Component {
  constructor(props){
    super(props)

    this.state = {
      contacts
    };

      this.onDismiss = this.onDismiss.bind(this);
  }

    onDismiss(id) {
    console.log(id)
    }

  render() {
    return (
      <div className="App">
          {
            this.state.contacts.map(function(contact, i){
              return(   
                   <div key={contact.id}>  <br></br> 
                    <div> First Name:</div>
                    <span> {contact.first_name}</span>
                      <div> Last Name:</div>
                    <span> {contact.last_name}</span>
                      <div> Email:</div>
                    <span> {contact.email}</span> 
                   <div> <button type="button" onClick={() => this.onDismiss(contact.id)}>Remove Contact </button> </div>
              
                </div>
                )
            })
          }




      </div>
    );
  }
}

export default App;


Solution

  • The problem is that you're using this inside a function, so this is bound by the function instead of the enclosing class. Try a lambda instead:

    this.state.contacts.map((contact, i) => (   
        <div key={contact.id}>
            <br /> 
            <div>First Name:</div>
            <span>{contact.first_name}</span>
                <div>Last Name:</div>
            <span>{contact.last_name}</span>
                <div>Email:</div>
            <span>{contact.email}</span> 
            <div>
                <button type="button" onClick={() => this.onDismiss(contact.id)}>
                    Remove Contact
                </button>
            </div>
        </div>
    )