I am trying to use material-ui's useScrollTrigger with a target other than window
like so:
export default props => {
let contentRef = React.createRef();
const scrollTrigger = useScrollTrigger({ target: contentRef.current });
return (
<React.Fragment>
<CustomHeader shrink={scrollTrigger} />
<div ref={contentRef}>
{props.children}
</div>
</React.Fragment>
);
};
This causes an error to be thrown because contentRef.current
is null when useScrollTrigger
is called. What is the proper usage of this utility with child elements as a target?
You were right, since the first time the component renders contentRef.current is null and so an error will be thrown.
We need two things a reference to the target Element, and a way to re-render so our scrollTrigger is calculated again. in other words we need a state.
The following code will work
export default props => {
// please keep it undefined here to not make useScrollTrigger throw an error on first render
const [scrollTarget, setScrollTarget] = useState(undefined)
const scrollTrigger = useScrollTrigger({ target: scrollTarget });
return (
<React.Fragment>
<CustomHeader shrink={scrollTrigger} />
<div ref={node => {
if (node) {
setScrollTarget(node);
}
}}>
{props.children}
</div>
</React.Fragment>
);
};
For you typescript users that feel left out, let me save you several hours of your lives figuring out the appropriate typing:
const [scrollTarget, setScrollTarget] = useState<Node | Window | undefined>()
const scrollTrigger = useScrollTrigger({ target: scrollTarget });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With