React - How do you get the top position of a styled component?

10,058

Solution 1

In react you would use a reference for your component: https://reactjs.org/docs/refs-and-the-dom.html

You would have something like this:

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }

  getOffset = () => {
    console.log(this.myRef.current.offsetTop);  
  }
  render() {
    return <Container ref={this.myRef} onClick={this.getOffset} />;
  }
}

And now you can access the container offsetTop by this.myRef.current.offsetTop inside of your onScroll function like in getOffset

Solution 2

Another option is to use an innerRef. This can be better because it will give you a reference to the DOM node and not just a wrapper. See this answer.

You would then have more direct access to properties like scrollTop.

Unlike ref, innerRef uses a callback:

In your case it would look like:

class MyComponent extends React.Component {

  constructor(props) {
    super(props);
    this.myRef;
  }

  getOffset = () => {
    console.log(this.myRef.offsetTop);  
  }

  render() {
    return <Container
        innerRef={element => this.textInput = element}
        onClick={this.getOffset} />;
  }
}
Share:
10,058

Related videos on Youtube

Max Lynn
Author by

Max Lynn

Updated on May 31, 2022

Comments

  • Max Lynn
    Max Lynn almost 2 years

    Something that used to be simple is quite complicated when you don't know the React way.

    I'm trying to create a component to act like a sticky header or footer when it reaches the top of the page.

    At the moment I'm quite content in adding the below:

      componentDidMount() {
        window.addEventListener('scroll', this.onScroll, false);
      }
    
      componentWillUnmount() {
        window.removeEventListener('scroll', this.onScroll, false);
      }
    

    However I've hit a wall to how I get the scroll top position of a styled component. So lets say I had a styled component called Container and that outputted a form I usually just add a data attribute and do something like the below:

    const container = document.getElementbyTag("data-sticky-container")
    const position = container.offsetTop 
    

    How would I go about doing this in React?


    Update

    Now using ref. I've fallen into a problem where current isn't defined:

      constructor(props) {
        super(props);
        this.optionBox = React.createRef();
      }
    
      componentDidMount() {
        window.addEventListener('scroll', this.onScroll, false);
      }
    
      componentWillUnmount() {
        window.removeEventListener('scroll', this.onScroll, false);
      }
    
      onScroll() {
        console.log(this.optionBox.current.offsetTop);
      }
    
  • Max Lynn
    Max Lynn over 5 years
    do you know why offsetTop would be undefined?
  • Laurenz Glück
    Laurenz Glück over 5 years
    sorry - you need to do this.myRef.current.offsetTop
  • Max Lynn
    Max Lynn over 5 years
    I'm getting an undefine on the current now. I'll update my answer with some more info. Thanks for your help so far
  • Laurenz Glück
    Laurenz Glück over 5 years
    I think you need to bind onScroll like this: this.onScroll = this.onScroll.bind(this); in your constructor
  • Max Lynn
    Max Lynn over 5 years
    ah your right! This has got me a few times! Thanks Laurenz
  • Laurenz Glück
    Laurenz Glück over 5 years
    No problem - by the way: if you use arrow functions like onScroll = () => {} you don't have to bind the function. More about this: reactarmory.com/answers/when-to-use-arrow-functions