React - How do you get the top position of a styled component?
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} />;
}
}
Related videos on Youtube
Max Lynn
Updated on May 31, 2022Comments
-
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 over 5 yearsdo you know why offsetTop would be undefined?
-
Laurenz Glück over 5 yearssorry - you need to do
this.myRef.current.offsetTop
-
Max Lynn over 5 yearsI'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 over 5 yearsI think you need to bind
onScroll
like this:this.onScroll = this.onScroll.bind(this);
in your constructor -
Max Lynn over 5 yearsah your right! This has got me a few times! Thanks Laurenz
-
Laurenz Glück over 5 yearsNo 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