2

I'm getting the error this.updateCSSAnimation is not a function, but i'm unsure why as I have bound it in my constructor. I have tried this.updateCSSAnimation with and without parenthesis but neither work.

import React from 'react'

class ScrollBG extends React.Component {
  constructor(props) {
    super(props)

    this.updateCSSAnimation = this.updateCSSAnimation.bind(this)
  }

  componentDidMount () {
    document.addEventListener('scroll', this.handleScroll)
  }

  componentWillUnmount () {
    document.removeEventListener('scroll', this.handleScroll)
  }

  handleScroll () {
    this.scroll = window.ScrollY

    this.globe = document.querySelector('.globe')
    this.map = document.querySelector('.map')

    this.updateCSSAnimation()
  }

  updateCSSAnimation () {
    const scroll = this.scroll

    this.globe.style.bottom = 0 + 200 * (scroll / 250) + 'px'
    this.map.style.width = 68 + (scroll / 50) + 'rem'
  }

  render () {

    return (
      <section className='map'>
        <div className='globe'>
         stuff
        </div>
      </section>
    )
  }
}

export default ScrollBG
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
user2953989
  • 2,791
  • 10
  • 36
  • 49

3 Answers3

4

In your case this in handleScroll - is a reference to document. document does not have updateCSSAnimation function. Instead of updateCSSAnimation you need to bind handleScroll function:

constructor(props) {
    super(props)

    this.handleScroll = this.handleScroll.bind(this)
  }
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Andrii Golubenko
  • 4,879
  • 1
  • 22
  • 27
1

you are calling this.updateCSSAnimation() from handleScroll which is why you are facing issue.

Simply bind this.handleScroll = this.handleScroll.bind(this) inside constructor

hope this helps, happy coding!!!

Darpan Rangari
  • 1,494
  • 11
  • 22
0

It's because of

 document.addEventListener('scroll', this.handleScroll)

and

document.removeEventListener('scroll', this.handleScroll)

your handleScroll function is being called in a different context so the use of this inside that function is not referring to ScrollBG.

if you bind(this) to handleScroll it should work fine.

ie

document.addEventListener('scroll', this.handleScroll.bind(this))

Depending on your env, you might also be able to take advantage of arrow functions by doing this:

handleScroll = () => {
  this.scroll = window.ScrollY

  this.globe = document.querySelector('.globe')
  this.map = document.querySelector('.map')

  this.updateCSSAnimation()
}

Arrow functions automatically bind(this) to a function but in order to take advantage of them in classes in the way I've described above, you'll need to have class properties enabled in your build env. Here's a simple example of context in JS with a class that has an arrow function and a regular method.

Reference:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

https://blog.pragmatists.com/the-many-faces-of-this-in-javascript-5f8be40df52e

DrBojingle
  • 11
  • 1