Darren
Darren

Reputation: 2290

Scroll position of a div id in parent component

Using ReactJS and GatsbyJS (v2) I have a header component that sits fixed over div id="outerContainer" in the parent layout component.

To toggle class on scroll position below 100px, I would generally use window.scrollY < 100.

However, due to the body class with the style overflow:hidden and outerContainer with overflow: scroll, the window scroll position does not change.

How can I define outerContainer.scrollY < 100 from a child component, whilst referencing the outerContainer of the parent for scroll position?

Layout.js

const Layout = ({ children }) => (
  <div>
    <div id="outerContainer" ref={el => (this.outerContainer = el)}>
      <div className="content">{children}</div>
    </div>
    <Header />
  </div>
);

Header.js

class Header extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      navScrolled: true
    };
    this.onScroll = this.onScroll.bind(this);
  }

  componentDidMount() {
    document.addEventListener('scroll', () => {
      const navScrolled = outerContainer.scrollY < 100;
      if (navScrolled !== this.state.navScrolled) {
        this.onScroll(navScrolled);
      }
    });
  }
  componentWillUnmount() {...}
  ...
}

My first thought is that I should perform function in layout.js and use props pass the state down. Is this the best option or perhaps is there another way that would keen everything in header.js?

Upvotes: 0

Views: 331

Answers (1)

cincplug
cincplug

Reputation: 1054

Your first thought is correct, parent class is proper place for your onScroll callback, because the scroll position is a property of your entire layout, not of header which only uses it.

Also, by keeping onScroll in parent class, you keep yourself able to pass it to outerContainer as well, if it grows into separate class during the development, which is likely to happen.

Upvotes: 1

Related Questions