Search code examples
reactjsformsevent-handlingstateref

React: onClick event.currentTarget.textContent returning onClick of undefined


In my website, it currently shows users a list of movies based on their input.

When user clicks on the title of the movie that is rendered, I want to setState(chosenOne: the movie title they clicked).

Currently, when I click on movie title, it returns an error stating the following:

Uncaught TypeError: Cannot read property 'onClick' of undefined
    at onClick (Fav.js:62)

Any way to fix this? Any help is greatly appreciated.

import React, { Component } from 'react'
import axios from 'axios';
import '../styles/Rec.scss'

export class Fav extends Component {
    constructor (props) {
        super (props) 
            this.state = {
                inputOne: '',
                chosenOne: '',
                movies:[],
            };
    }

    onChangeOne = (event) => {
        this.setState({
            inputOne: event.target.value
        },()=>{
            if(this.state.inputOne && this.state.inputOne.length > 1) {
                this.getInfo()
            } else {
            }
        })

    }

    onClick = (event) =>{
        this.setState({
            chosenOne: event.currentTarget.textContent
        })
        console.log(this.state.chosenOne)
    }

    onSubmit = (event) => {
        event.preventDefault();
    }

    getInfo = () => {
        let url = `https://api.themoviedb.org/3/search/movie?api_key=''&language=en-US&query='${this.state.inputOne}'&page=1&include_adult=false`
        axios.get(url)
        .then(res => {
        if (res.data) {
            const movieData = res.data.results.filter(movie => movie.poster_path != null);
            this.setState({movies: movieData});
        }
        console.log(this.state.movies)
    })
    }

    render() {
        return (
            <div>
                <h1>Favorite Movie of All Time</h1>
                <form onSubmit={this.onSubmit}>
                    <input onChange={this.onChangeOne}/>
                    <div className="rec__container">
                        {this.state.movies && this.state.movies.slice(0,3).map(function(movie, genre_ids) {
                            return(
                                <div className="rec__sample">
                                    <img className="rec__img" src={`https://image.tmdb.org/t/p/w500/${movie.poster_path}`} alt="movie poster"/>
                                    <p onClick={event => this.onClick(event)}>{movie.title}</p>
                                </div>
                            )
                        })}
                    </div>
                </form>
            </div>
        )
    }
}

export default Fav


Solution

  • I am quite sure the problem is that this in this.onClick is undefined. This happens when it is not bound correctly to the the class.

    I would recommend to change the function declared after map to an arrow function.

    <div className="rec__container">
      {this.state.movies &&
        this.state.movies.slice(0, 3).map((movie, genre_ids) => {
          return (
            <div className="rec__sample">
              <img className="rec__img" src={`https://image.tmdb.org/t/p/w500/${movie.poster_path}`} alt="movie poster" />
              <p onClick={event => this.onClick(event)}>{movie.title}</p>
            </div>
          );
        })}
    </div>;
    

    Also, you are binding onClick function in your constructor as well as using it as an arrow function. Bind does not work on arrow functions.

    Either remove this.onClick = this.onClick.bind(this) or convert onClick into a simple function rather than an arrow function.