aalok89
aalok89

Reputation: 181

Need Reactjs help on how to properly pass this function from the parent to child button component

Brand new to reactjs so bear with me.
- I have a MovieContainer component that returns a table.
- I have a child MovieCell component which will be placed inside the MovieContainer and iterated over an array of objects. Inside the cell is a delete button that will filter the list array to remove the clicked item
- I have the the delete function prepared in the MovieContainer component but I'm not sure the proper way to pass it to the child.

github link
MovieContainer Component:

class MoviesContainer extends Component {
  constructor(props) {
    super(props);

    this.state = {
      movies: getMovies()
    };

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

  deleteMovie(movie) {
    const movies = this.state.movies.filter(m => m._id !== movie._id);
    this.setState({
      movies: movies
    });
    console.log(this);
  }

  render() {
    return (
      <table className="table">
        <thead>
          <tr>
            <th>Title</th>
            <th>Genre</th>
            <th>Stock</th>
            <th>Rate</th>
          </tr>
        </thead>
        <tbody>
          {this.state.movies.map(movie => (
            <MovieCell
              key={movie._id}
              title={movie.title}
              genre={movie.genre.name}
              numberInStock={movie.numberInStock}
              dailyRentalRate={movie.dailyRentalRate}
              deleteMovie={this.deleteMovie}
            />
          ))}
        </tbody>
      </table>
    );
  }
}

MovieCell Component:

class MovieCell extends Component {
  constructor(props) {
    super(props);

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

  handleDelete(movie) {
    this.props.deleteMovie(movie);
  }

  render() {
    const title = this.props.title;
    const genre = this.props.genre;
    const numberInStock = this.props.numberInStock;
    const dailyRentalRate = this.props.dailyRentalRate;

    return (
      <tr>
        <td>{title}</td>
        <td>{genre}</td>
        <td>{numberInStock}</td>
        <td>{dailyRentalRate}</td>
        <td>
          <button onClick={movie => this.handleDelete(movie)}>Delete</button>
        </td>
      </tr>
    );
  }
}

Upvotes: 2

Views: 26

Answers (1)

Tholle
Tholle

Reputation: 112787

You are currently naming the event to movie and using that as your movie object which will not work as expected.

You could instead pass down the movie id as a prop and use that instead of the event when you call handleDelete.

class MoviesContainer extends Component {
  // ...

  deleteMovie(movieId) {
    const movies = this.state.movies.filter(m => m._id !== movieId);
    this.setState({
      movies: movies
    });
  }

  render() {
    return (
      <table className="table">
        <thead>
          <tr>
            <th>Title</th>
            <th>Genre</th>
            <th>Stock</th>
            <th>Rate</th>
          </tr>
        </thead>
        <tbody>
          {this.state.movies.map(movie => (
            <MovieCell
              key={movie._id}
              id={movie._id}
              title={movie.title}
              genre={movie.genre.name}
              numberInStock={movie.numberInStock}
              dailyRentalRate={movie.dailyRentalRate}
              deleteMovie={this.deleteMovie}
            />
          ))}
        </tbody>
      </table>
    );
  }
}

class MovieCell extends Component {
  // ...

  handleDelete() {
    this.props.deleteMovie(this.props.id);
  }

  render() {
    const title = this.props.title;
    const genre = this.props.genre;
    const numberInStock = this.props.numberInStock;
    const dailyRentalRate = this.props.dailyRentalRate;

    return (
      <tr>
        <td>{title}</td>
        <td>{genre}</td>
        <td>{numberInStock}</td>
        <td>{dailyRentalRate}</td>
        <td>
          <button onClick={this.handleDelete}>Delete</button>
        </td>
      </tr>
    );
  }
}

Upvotes: 2

Related Questions