danedelions_swift
danedelions_swift

Reputation: 125

ReactJS: React CountUp visible only once in visibility sensor

I am working on a page that has a visibility sensor so that whenever I scroll to that section, the animation starts. However, I only need it to be visible only once.

const [scrollStatus, setScroll] = useState(false);
    const contextData = {
        stateSetters: {
            scrollStatus
        }

    }
<ScrollContext.Provider value={contextData}>
    <VisibilitySensor onChange={() => {
       setScroll(!scrollStatus);
    }}>
    <CountUp start={0} end={scrollStatus ? 0 : 40} duration={1.75} suffix="+"/>
    </VisibilitySensor>
</ScrollContext.Provider>

I am currently using hooks and functional components. I have been looking for ways to be able to set the visibility to true once it has been viewed.

The output should become already visible and not visible only every scroll.

Upvotes: 0

Views: 2757

Answers (3)

Arijit Kundu
Arijit Kundu

Reputation: 547

This is an easy example of using react-countup and react-visibility-sensor for viewing the effect for once only

import React from "react";
import CountUp from "react-countup";
import VisibilitySensor from "react-visibility-sensor";

function Milestones() {
    const [focus, setFocus] = React.useState(false);
    return (
        <CountUp start={focus ? 0 : null} end={150} duration={4} redraw={true}>
            {({ countUpRef }) => (
                <VisibilitySensor onChange={(isVisible) => {
                    if (isVisible) { setFocus(true); }
                }}>
                    <span ref={countUpRef} />
                </VisibilitySensor>
            )}
        </CountUp>
    )
}

export default Milestones;

Upvotes: 0

Rene
Rene

Reputation: 1214

As mentioned by dee zg, you can set the status of the VisibilitySensor by using the event attribute isVisible and the property active, as roughly shown in the following example.

A small running code example can be found on codesandbox.

import React from "react";
import VisibilitySensor from "react-visibility-sensor";

class myTest extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            VizSensorActive: true
        };

        this.do_something = this.do_something.bind(this);
    }

    do_something(isVisible) {
        if (isVisible) {
            this.setState({ VizSensorActive: false });
        }
    }

    render() {
        return (
            <VisibilitySensor
                active={this.VizSensorActive}
                onChange={this.do_something}
            >
                <div>Test</div>
            </VisibilitySensor>
        );
    }
}

export default myTest;

Upvotes: 1

tlt
tlt

Reputation: 15261

You probably don’t want to toggle state unconditionally but rather just set it to true once your visibility sensor calls its onChange callback with isVisible=true

So, something like this (i havent tested it):

function handleVisibility(isVisible) {
!scrollStatus &&
isVisible &&
setScroll(isVisible);
}

<VisibilitySensor onChange={handleVisibility}>

Upvotes: 0

Related Questions