Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React — onScroll listener for parent element?

Tags:

reactjs

How can I add an onScroll listener in a component to catch a scroll of a parent element?

class ChildDiv extends React.Component {
  constructor() {
    super();
  }
  handleScrollOfParent() {
    // do stuff when parent <main> scrolls;
  }
  render() {
    return (
      <div id="child" onScroll={this.handleScrollOfParent.bind(this)}>
        // content with overflow: hidden and scroll handled by parent MAIN.
      </div>
    )
  }
}
export default ChildDiv;

Rendered in a parent main, like this <main><ChildDiv /></main> and I want to catch the scroll of the main.

like image 769
Kirk Ross Avatar asked Jul 19 '16 17:07

Kirk Ross


2 Answers

You could either:

1) try to grab the parent node from the child component:

componentDidMount() {
  ReactDOM.findDOMNode(this).parentNode.addEventListener(...
}

2) pass the parent node as props and attach listener after rendered:

In parent:

render{
  return(
    <div className="parent" ref={(elem)=>{this.node=elem}}>
      <Child parentNode={this.node}/>
    </div>
  )
}

and in child (parentNode is still undefined in constructor, check in next props):

componentWillReceiveProps(newProps){
  newProps.parentNode.addEventListener(...
}
like image 68
user5480949 Avatar answered Sep 28 '22 01:09

user5480949


According to React's nature, which is passing props from Parent down to Children, so when you want the Child element to update its parent, you need to create a function on Parent, and pass to the Child as props

Please also refer to my answer to a similar issue (how to trigger the parent component to do something from the child/grandchild/or great-grandchild):

Re-initializing class on redirect

In your case, we may do something like this:

1/ Create a function on Parent that trigger the Parent itself to do something:

import React from 'react';

class Parent extends React.Component {

  constructor(props) {
    super(props);
    // ...
  }

  doSomeThingOnParent = () => {
    // do whatever you want with this Parent component, setState, forceUpdate etc.
  }

  render(){
    // ...
    <Child doSomeThingOnParent={this.doSomeThingOnParent} />
    // ...
  }
}

2/ On Child Component, trigger the above function using onScroll:

class Child extends React.Component {
  ...
  render() {
    return (
      <div id="child" onScroll={this.props.doSomeThingOnParent}>
        // your content
      </div>
    )
  }
}

However, you cannot render the Parent by your mentioned way, which is:

You should use like the Parent's render method above, and also set the CSS to allow overflow for your Child component

like image 43
thinhvo0108 Avatar answered Sep 28 '22 01:09

thinhvo0108