react-waypoint icon indicating copy to clipboard operation
react-waypoint copied to clipboard

Disable Waypoints temporarily

Open AndreasFaust opened this issue 7 years ago • 5 comments

Hello there! First of all: Thanks for this nice tool! What is the best method to dis- and re-enable waypoints on demand? Is there a method like in the original waypoints-library?

AndreasFaust avatar May 10 '18 13:05 AndreasFaust

One idea is:

{showWaypoint && <Waypoint {...props} />}

showWaypoint could be a value stored within component state. You can then set the state, and the waypoint will mount and i mount accordingly.

jamesplease avatar May 10 '18 13:05 jamesplease

Thanks for replying so quickly! If the waypoint has children, they would also be unmounted. I just don't want it to trigger for a certain time, not to disappear. I solved it with a if-return-statement in the onEnter- and onLeave-callback, which isn't a hard thing to do. But I thought maybe there's a better, generalized way to achieve this.

AndreasFaust avatar May 10 '18 14:05 AndreasFaust

That’s great that you were able to achieve what you were trying to do. I can see why you might prefer a declarative solution over the imperative one that you’re using, though. We have made an effort to keep the props lean, but if there’s a need for something new to help with disabling, I am sure it would at least be considered.

Can you tell us more about your use case? And would you mind sharing the code you ended up going with so we can get a sense of how much of a “workaround” it is?

jamesplease avatar May 10 '18 14:05 jamesplease

Sure. I wrote a simple component for image-lazyloading. It contains two waypoints: One to preload the image when it has a certain distance, and a second to animate it, when it's in sight.

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import Waypoint from 'react-waypoint'

export default class getWaypoints extends Component {
    static propTypes = {
        onViewportEnter: PropTypes.func,
        onViewportLeave: PropTypes.func,
        onLoadEnter: PropTypes.func,
        onLoadLeave: PropTypes.func,
        loadTopOffset: PropTypes.number,
        loadBottomOffset: PropTypes.number,
        disable: PropTypes.bool,
        children: PropTypes.node,
    }

    static defaultProps = {
        onViewportEnter: undefined,
        onViewportLeave: undefined,
        onLoadEnter: undefined,
        onLoadLeave: undefined,
        loadTopOffset: 0,
        loadBottomOffset: 0,
        children: null,
        disable: false,
    }

    onLoadEnter = () => {
        if (this.props.disable) return
        if (this.props.onLoadEnter) this.props.onLoadEnter()
    }
    onLoadLeave = () => {
        if (this.props.disable) return
        if (this.props.onLoadLeave) this.props.onLoadLeave()
    }
    onViewportEnter = () => {
        if (this.props.disable) return
        if (this.props.onViewportEnter) this.props.onViewportEnter()
    }
    onViewportLeave = () => {
        if (this.props.disable) return
        if (this.props.onViewportLeave) this.props.onViewportLeave()
    }

    getPreload = () => (
        <Waypoint
            key="WaypointPreload"
            onEnter={this.props.onLoadEnter}
            onLeave={this.props.onLoadLeave}
            topOffset={-this.props.loadTopOffset}
            bottomOffset={-this.props.loadBottomOffset}
        >
            <div className="waypoint--preload" style={{ width: '100%' }}>
                {this.props.children}
            </div>
        </Waypoint>
    )

    render() {
        return (
            <Waypoint
                key="WaypointViewport"
                onEnter={this.props.onViewportEnter}
                onLeave={this.props.onViewportLeave}
            >
                <div className="waypoint--viewport" style={{ width: '100%' }}>
                    {this.props.loadTopOffset > 0 || this.props.loadBottomOffset > 0
                        ? this.getPreload()
                        : this.props.children
                    }
                </div>
            </Waypoint>
        )
    }
}

AndreasFaust avatar May 10 '18 14:05 AndreasFaust

@jamesplease any further thoughts on the above?

@AndreasFaust another solution could be to not pass the callback function when you want the Waypoint disabled. Both the onEnter and onLeave props are optional, so you could so something like:

<Waypoint
  onEnter={disabled ? undefined : this.handleOnEnter}
/>

One downside to that is that it may cause the Waypoint to re-render since the props have changed.

MatthewHerbst avatar Jun 07 '18 18:06 MatthewHerbst