-1

I have the following code, and I want to add an even handler for detecting when delete button is clicked and then remove the specific item from list.

Favorites.js

 constructor(props) {
        super(props);
        this.state = {
            movies: []
        };

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

MovieList.js

export default ({ movies }) => {
    return(
        <div id="saved-movies-list">
        <ul className="saved-movies-list">
        { movies.map(movie => <li key={ movie.imdbID }><Movie movie={ movie } /></li>) }
        </ul>
        </div>
    )
};

Movie.js

const Movie = ({movie}) => {
     return (<div className="movie-card" id={movie.imdbID}>     
          {
               // eslint-disable-next-line
               movie.poster == 'N/A' ? 
               <div className="movie-card-poster missing">
               <img className="d-block h-100" src={movie_poster} alt="" /> 
               </div>
               :
               <div className="movie-card-poster">
               <img className="d-block h-100" src={movie.poster} alt="" />
               </div>
          }
          <div className="body">
               <div style={{ maxWidth: '80%' }}>
                    <h5 class="card-title">{movie.title}</h5>
               </div>
               <p className="text-secondary">{ movie.year }</p>
               {!movie.runtime ? "" : <p className="text-secondary">{ movie.runtime }</p>}
               <p className="plot">{movie.description}</p>
               <a href="#" className="delete-movie" title="Remove this movie"><FontAwesomeIcon icon="minus-circle" size="1x" /></a>
          </div>
     </div>)
}

I need to attach event to this line:

       <a href="#" className="delete-movie" title="Remove this movie"><FontAwesomeIcon icon="minus-circle" size="1x" /></a>

But, I do NOT know how to? Writing this.props. ... does not work!

John Smith
  • 465
  • 4
  • 15
  • 38

4 Answers4

1

In Movie component:

Add a callback prop in your Movie component, call whatever you like e.g.: onDelete.

Then add handleClick handler that calls your callback prop,

const handleClick = (event) => {
  event.preventDefault();

  props.onDelete(); // This callback is coming from your `Movie` props.
}

and pass it to your anchor element's onClick attribute.

<a
  href="#"
  className="delete-movie"
  title="Remove this movie"
  onClick={handleClick}
>
  <FontAwesomeIcon icon="minus-circle" size="1x" />
</a>

In MovieList component:

Add a callback prop in your MovieList component and call it onDeleteMovie.

export default (props) => {

Then pass it in your Movie's onDelete prop like this:

{props.movies.map((movie, index) => 
  <li key={index}> // since imdbID is not unique after all use the index
    <Movie
     movie={movie}
     onDelete={() => props.onDeleteMovie(index)}
    />
  </li>
)}

In Favorites component:

Add a handleDelete method in Favorites component that looks like this.

handleDelete(index) {
  const movies = [...this.state.movies];

  movies.splice(index, 1);

  this.setState({ movies });
}

and pass it to your MovieLists onDeleteMovie prop.

<MovieList
  movies={this.state.movies}
  onDeleteMovie={this.handleDelete}
/>
Ioannis Potouridis
  • 1,246
  • 6
  • 7
  • Ioanns, it removes everything? – John Smith Jun 02 '20 at 06:45
  • When I click, to remove one single item, it removes all? – John Smith Jun 02 '20 at 06:48
  • 1
    Well, do they have common imdbID? – Ioannis Potouridis Jun 02 '20 at 07:02
  • Good question, I will check now. – John Smith Jun 02 '20 at 07:05
  • Yes, you were correct. Can I ask, why aren't the specific items removed from the array? – John Smith Jun 02 '20 at 07:09
  • I am printing the state, after, and it still shows me the items, even if it is removed in the view? setState does not seem to work? – John Smith Jun 02 '20 at 07:11
  • 1
    It is expected then that all items are removed. This is why I work with index when I don't know the data. I can change the answer to work with index one last time. – Ioannis Potouridis Jun 02 '20 at 07:13
  • 1
    I've updated the answer one last time. Try it this way. Good luck. :-) – Ioannis Potouridis Jun 02 '20 at 07:17
  • Ioannis, `this.setState({ movies });` it does not seem to make any changes? Do you know why? – John Smith Jun 02 '20 at 07:21
  • 1
    Can you share your movies state? – Ioannis Potouridis Jun 02 '20 at 07:31
  • `this.state = { movies: [] };` that's in the constructor of **favorites.js** – John Smith Jun 02 '20 at 07:33
  • Then I am doing what you told me! – John Smith Jun 02 '20 at 07:34
  • Here's something, that seems wrong, `onDelete={props.onDeleteMovie(movie.imdbId)}` in my
  • during map, having it like that, it will not render anything. Changing it to: `onDelete={() => props.onDeleteMovie(movie.imdbId)}` and you'll get nothing working.
  • – John Smith Jun 02 '20 at 07:45
  • 1
    I figured out the problem in the end! Thanks a lot dude. – John Smith Jun 02 '20 at 08:39