Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the usage of material-ui useScrollTrigger with child target ref?

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?

like image 577
CuddleBunny Avatar asked Jun 11 '19 20:06

CuddleBunny


2 Answers

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>
    );
};
like image 140
ehab Avatar answered Oct 03 '22 11:10

ehab


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 });
like image 20
Matt Tilson Avatar answered Oct 03 '22 11:10

Matt Tilson