Search code examples
reactjshtml5-videosetstatemouseenter

How can I play video in React on mouseEnter


I would like to play video on mouseeEnter and pause on mouseLeave. Everytime I try this I get TypeError: Cannot read property 'play' of undefined.

When I console.log e.currentTarget I receive correct tag.

This is what I did so far


import { MoviesList, MoviesListEl, Title, VideoWrap, MediaWrap, MovieDesc, MobilePreview } from "./styles"

export default class FetchRandomMovies extends React.Component {
  state = {
    loading: true,
    movies: []
  }

  async componentDidMount() {
    const url = "https://itunes.apple.com/us/rss/topmovies/limit=100/json"
    const response = await fetch(url)
    const data = await response.json()

    this.setState({ movies: data.feed.entry, loading: false })
  }

  getInitialState(e) {
    return {
      isPlaying: false
    }
  }
  mouseEnter = e => {
    this.setState({ isPlaying: true })
    console.log(e)
  }
  mouseLeave = e => {
    this.setState({ isPaused: false })
  }

  render() {
    if (this.state.loading) {
      return <div>loading...</div>
    }

    if (!this.state.movies.length) {
      return <div>didn't get movies</div>
    }
    return (
      <MoviesList>
        {this.state.movies.map(item => (
          <MoviesListEl key={item.title.label}>
            <Title>
              <span>{item.title.label}</span>
              <span>{item.category.attributes.term}</span>
            </Title>
            <MediaWrap>
              <img src={item["im:image"][2].label} alt="" />
              <VideoWrap>
                <video onMouseEnter={e => this.mouseEnter(e.currentTarget).play()} controls>
                  <source src={item.link[1].attributes.href} type="video/x-m4v" />
                </video>
              </VideoWrap>
            </MediaWrap>
            <MovieDesc>{item.summary.label}</MovieDesc>
            <MobilePreview href={item.link[1].attributes.href} />
          </MoviesListEl>
        ))}
      </MoviesList>
    )
  }
}

Probably on this line is something wrong:

<video onMouseEnter={e => this.mouseEnter(e.currentTarget).play()} controls>

Thank you in advance


Solution

  • You are calling .play() on the wrong value. You are intending to call .play() on e.currentTarget, but that's not what your code says. Your code calls .play() on the void return from this.mouseEnter(e.currentTarget).

    You can fix this a number of ways, the simplest one is to call play() within your mouseEnter callback. Since this callback is supposed to take the event, we want to pass it e rather than e.currentTarget. But since e is the default argument we can just provide our function to onMouseEnter.

    <video onMouseEnter={this.mouseEnter} controls>
    
    mouseEnter = e => {
        e.currentTarget.play();
        this.setState({ isPlaying: true });
        console.log(e);
    }