3

I'm making a personal website in react, and I wanted to do some tricks with scrolling, but ya know how it goes, getting stuck on step one. All I have in my react is

  class App extends Component {
  makeTextLarger(e) {
    console.log(e)
    console.log("scrolling")
  }
  componentDidMount() {
      const list = ReactDOM.findDOMNode(this.refs.test)
      console.log(list)

      list.addEventListener('scroll', this.makeTextLarger);
  }
  componentWillUnmount() {
      const list = ReactDOM.findDOMNode(this.refs.test)
      list.removeEventListener('scroll', this.makeTextLarger);
  }
  render() {
    var style = {
      height: '10000px',
      fontSize: 200,
      background: 'blue'
    };
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title"</h1>
        </header>
        <p className="App-intro">
          text to be made bigger at some point
        </p>
        <div ref="test" style={style}>
          Pls
        </div>
      </div>
    );
  }
}

In which nothing fires as I scroll. If I instead look at use window instead of the specific div, it works. When I console.log the list, it does indeed return an html object, so Im not sure why my binding is working selectively. Any thoughts?

Joel Hines
  • 229
  • 1
  • 4
  • 12

2 Answers2

0

You can add an event listener to your component that reads the "scroll" event.

For example, here's a rewrite to your component. Only the methods were changed, no refs were added:

class App extends Component {
  constructor() {
    super()
    this.state = {
      count: 0
    }
  }
  componentDidMount() {
    window.addEventListener('scroll', this.handleScroll)
  }

  componentWillUnmount() {
    window.removeEventListener('scroll', this.handleScroll)
  }
  handleScroll = () => {
    this.setState(
      { count: this.state.count + 1 },
      console.log('Scroll', this.state.count)
    )
  }
  render() {
    var style = {
      height: '10000px',
      fontSize: 200,
      background: 'blue'
    }
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title" />
        </header>
        <p className="App-intro">text to be made bigger at some point</p>
        <div ref="test" style={style}>
          Pls
        </div>
      </div>
    )
  }
}

You'll get a steady stream of console.logs to your browser with this. It should be close to accurate, but not perfect, since this.setState is asynchronous.

You can also pass in the event itself with handleScroll = (e) => {

For reference: Update style of a component onScroll in React.js

Denny
  • 744
  • 4
  • 10
-1

try using the onScroll handler react offers

  render() {
    var style = {
      height: '10000px',
      fontSize: 200,
      background: 'blue'
    };
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title"</h1>
        </header>
        <p className="App-intro">
          text to be made bigger at some point
        </p>
        <div onScroll={this. makeTextLarger} style={style}>
          Pls
        </div>
      </div>
    );
  }
}

if you insist on using a ref

<div ref={ref => this.title = ref} style={style}>
          Pls
</div>

then in your lifecycle methods use this.title.

lastly always bind your event handlers

makeTextLarger = (e) => {
    console.log(e)
    console.log("scrolling")
  }
Joey
  • 1,075
  • 8
  • 13