Code Monkey home page Code Monkey logo

react-page-visibility's Introduction

React Page Visibility

Declarative, nested, stateful, isomorphic page visibility for React

Build Status

Motivation

Are you polling your Backend on an interval basis? Are you running animations? What do you do if your tab is no longer visible?

See more classic use-cases in MDN Page Visibility API.

Well now you can react (Pun intended) to your app being in the background and invisible by conserving bandwidth and GPU calculations with ease. Introduction React Page Visibility:

  • A React higher order component that wraps the page visibility API
  • Cross-browser support (Yes, even IE and Safari)
  • Safe fallback if browser does not support it
  • Can be used multiple times anywhere in your application without side effects
  • Lets you decide how to handle the page being invisible and turning visible again

Why use a React component and not a helper function?

Because React is cool. 'Nuff said.

But really, why not use a helper function? Because you will then need to addEventListener and removeEventListener in your component lifecycle and that gets tedious.

Also, every time you use it you will need to check if your user's browser supports it and that gets tedious too.

Instead with react-page-visibility everything is taken care of for you.

Installation

$ npm install --save react-page-visibility

Usage

A rotating carousel component that will be passed down a prop of whether to rotate the images or not based on whether page is visible.

Using the usePageVisibility hook

import React from 'react';
import { usePageVisibility } from 'react-page-visibility';

const AppContainer = () => {
    const isVisible = usePageVisibility()

    return <RotatingCarousel rotate={isVisible} />
}

Using onChange callback

import React from 'react';
import PageVisibility from 'react-page-visibility';

class AppContainer extends React.Component {
    state = {
        rotate: true
    };

    handleVisibilityChange = isVisible => {
        this.setState({ rotate: !isVisible });
    }

    render() {
        return (
            <PageVisibility onChange={this.handleVisibilityChange}>
                <RotatingCarousel rotate={this.state.rotate} />
            </PageVisibility>
        );
    }
}

Using children as function callback

import React from 'react';
import PageVisibility from 'react-page-visibility';

const AppContainer = () => {
    return (
        <PageVisibility>
            { isVisible => <RotatingCarousel rotate={isVisible} /> }
        </PageVisibility>
    );
}

API

react-page-visibility is an higher order component, you can pass to it an onChange function:

onChange(handler)

Where handler is the callback to run when the visibilityState of the document changes:

Function handler(<Boolean> isVisible, <String> visibilityState)

  • isVisible is a Boolean indicating whether document is considered visible to the user or not.
  • visibilityState is a String and can be one of visible, hidden, prerender, unloaded (if your browser supports those)

Notice: previous versions had different arguments in the handler

Or you can use function as children pattern, where children is the callback to run when the visibilityState of the document changes.

Function children(<Boolean> isVisible, <String> visibilityState)

See MDN Page Visibility API Properties overview

License

MIT © Gilad Peleg

react-page-visibility's People

Contributors

chegger avatar clemencov avatar dbismut avatar devinrhode2 avatar frontendphil avatar jeremykay avatar pgilad avatar simonewebdesign avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

react-page-visibility's Issues

Not very useful - Visibility API vs blur/focus

Implementation of this library is quite good, but the Visibility API is not very useful at all.
It says what page is visible when it is actually hidden by and overlaying window.

E.g. if you are using it in a messenger, and messenger shows title/favicon notification if page is not visible, it will confuse the user: if user minimizes the browser or changed the tab, it works, but if he activates another application window, it doesn't. This behaviour will look like a bug.

This library can be used for some special cases, even in React, but not for wide usage.

Fallback for older browser (IE ==> document.focusin window.onpageshow window.onfocus) Make a perfect module !!

Can you add fallback for older browser please

You can't just add a comment like that https://github.com/pgilad/react-page-visibility/blob/master/src/utils.js#L42

(function() {
  var hidden = "hidden";

  // Standards:
  if (hidden in document)
    document.addEventListener("visibilitychange", onchange);
  else if ((hidden = "mozHidden") in document)
    document.addEventListener("mozvisibilitychange", onchange);
  else if ((hidden = "webkitHidden") in document)
    document.addEventListener("webkitvisibilitychange", onchange);
  else if ((hidden = "msHidden") in document)
    document.addEventListener("msvisibilitychange", onchange);
  // IE 9 and lower:
  else if ("onfocusin" in document)
    document.onfocusin = document.onfocusout = onchange;
  // All others:
  else
    window.onpageshow = window.onpagehide
    = window.onfocus = window.onblur = onchange;

  function onchange (evt) {
    var v = "visible", h = "hidden",
        evtMap = {
          focus:v, focusin:v, pageshow:v, blur:h, focusout:h, pagehide:h
        };

    evt = evt || window.event;
    if (evt.type in evtMap)
      document.body.className = evtMap[evt.type];
    else
      document.body.className = this[hidden] ? "hidden" : "visible";
  }

  // set the initial state (but only if browser supports the Page Visibility API)
  if( document[hidden] !== undefined )
    onchange({type: document[hidden] ? "blur" : "focus"});
})();

Look at this stackoverflow comments this is easy https://stackoverflow.com/a/1060034/10294022

for IE 9 you need to use document.onfocusin and document.onfocusout

And for Safari adn the other you need to use window.onpageshow window.onpagehide
window.onfocus window.onblur

Would you like me to do it ? Do you have just 10 minutes to spend ? You know your code this is gonna be very fast for you !!! please

Broken import in 4.2.0

The 4.2.0 release seems to be broken:

ERROR in ./node_modules/react-page-visibility/dist/index.es5.js Module not found: Error: Can't resolve './PageVisibility' in '/Users/martin/Projects/****/node_modules/react-page-visibility/dist'

Support React 18

Currently, react-page-visibility does not support React 18, which was released a couple of weeks ago.

Thus, when using react-page-visibility and react: ^18.0.0, npm finds conflicting peer deps when running npm install, making the install job fail.

We should simply add react 18.0.0 to the react peerDependency.

TypeError from usePageVisibility hook when visibility API isn't supported

This line blows up when visibility API isn't supported (e.g. server-side rendering):

const [initiallyVisible] = getHandlerArgs();

getHandlerArgs tries to extract properties from visibility, which is null:

TypeError: Cannot read property 'hidden' of null

Should this be protected by an isSupportedLocal conditional? Or should getHandlerArgs short-circuit when visibility is null?

Missing changelog

There's no changelog nor release descriptions.
I see a new major version, which implies potentially breaking changes, but no info anywhere..

Webpack production build issue - UglifyJS can't minify ES6

Overview

When using this package within our project, when building for production using webpack we get an UglifyJS error, it appears it's trying to minify ES6 code which it doesn't support.

ERROR in 0.js from UglifyJs
Unexpected token: punc (() [./~/react-page-visibility/index.js:10,0][0.js:25213,22]

We did look at upgrading to uglify-es but unfortunately, the webpack uglify-js plugin doesn't currently support the new API.

I'll raise a PR against this issue which will create a new webpack build which will allow us to use this package within our project. Just to note I've noticed a few additional updates which can be done so I'll bundle these in also. If you're not happy in the review we can switch things out etc.

npm warning when using React 16

Hey, I may be mistaken cause I am new to React, but it seems that this package is pinned on React 15, which creates the following warning when using npm with React 16:

npm WARN [email protected] requires a peer of react@^15.5.4 but none is installed. You must install peer dependencies yourself.

Now I just tried it with 16 anyway and it seems that at least for my usecase, this still works great. Would it be possible to unpin or at least add React 16 to possible dependencies?

Cheers

Components Showing as Visible on load?

I want to know if components from a list of components are on the screen on load so that I can tell it get additional data from the DB but not get the additional data of the other components until they are visible (user scrolls down).

I have a page that on load queries the DB for new items. When it returns it populates the screen with a list of components:

{items.map(item => {
    return (
        <CustomComponent key={`MCL${item._id}`} />
    );
})}

So on load items is equal to [] and then after it gets the items prints the <CustomComponent /> to screen. There are over 50 items and it only takes 10 <CustomComponent />'s to fill the screen so about 40 of them should not be visible.

In the customer component I have:

import {usePageVisibility} from "react-page-visibility";

function CustomComponent(props) {
    const isVisible = usePageVisibility();
    console.log("isVisible 0", isVisible);
    useEffect(() => {
        console.log("isVisible 1", isVisible);
    }, [isVisible]);
}

On load, I see in the console isVisible 0 true and isVisible 1 true 50 times but never see it print isVisible as false unless change tabs os something similar. I would expect it to print isVisible 0 true about 10 times and then isVisible 0 false about 40 times.

Error with npm - Could not resolve dependency

I updated my package dependencies and am running into this error when I try to install react-page-visibility (6.3.0):

Screen Shot 2021-01-15 at 4 15 18 PM

Any plans to fix this or should I run the command to force an incorrect/possibly broken resolution?

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.