Giter VIP home page Giter VIP logo

use-viewport-sizes's People

Contributors

dependabot[bot] avatar jaxonwright avatar micah-redwood avatar rob2d 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

Watchers

 avatar  avatar

use-viewport-sizes's Issues

Ability to pass a function which may prevent re-render of React Tree on viewport changes

when using viewport sizes library, the implementation itself is pretty optimal for what it does. But there are some cases where we may want to prevent re-rendering or updating of returned value unless the viewport meets some criteria. This would then let React go without passing through subsequent hooks which need to check for a diff; e.g. useMemo. While it's not necessarily expensive, the browser is already doing a lot of work internally to reflow CSS.

Another very common use case would be for emulating media viewports e.g. max width or min width. Since React would not know the difference on a media query without passing a callback, this library can also be a really nice fill in replacement with much less overhead (which in large part it is meant for). This would also decrease the stutter or jankness when resizing some screens and when it's only relevant in certain breakpoints (for example when using Material UI @ material-ui.com breakpoints).

Currently considering to do this via a passed in callback function (not a hook), with a return value that is observed (e.g. internally via useMemo) that can detect change triggers to return new values. This way from the outside calling hook fn/component, it may or may not update.

Example usage as follows:

(callback declared once above fn component)

/**
  * when callback returns 'sm' or 'md', render one time
  */
const getVpBreakpoint= ({ vpW, vpH }) => {
     return vpW < 200 ? 'sm' : 'md';
};

(within component)

/**
  * will only recompute and return sizes when the observer
  * function changes; this ensures things do not re-render,
 * and the additional memorized property is available as
 * the third param now.
 *
 * the main convenience is that the callback is ran on
 *every viewport change, but the component is not forced 
*  to re-render! So this is much less boilerplate than
 * observing via callbacks.
  */
const [vpW, vpH, vpBreakpoint] = useVpSizes(shouldUpdateVpSizes);

No SSR Support.

I looked through the source code and noticed that the window variable was global, so I was uncertain of how this would work with SSR. I setup up a codesandbox with NextJS and my assumptions were true: this fails in SSR as window is only defined client side.

I tried calling the cmponent when the parent component is mounted, but didn't work.

Here's what I tried: https://codesandbox.io/s/wnnx49708

I don't know what would be the consecuences of declaring window inside a useEffect to ensure the window variable exists, as useEffect is only called by the Client-side of the app.

I will be open for comment and sicussion, and maybe help, to add SSR suppport to this cool hook.

Standard Import and Variable Function Causes Elements to Disappear on Basic Frontend

To replicate this bug, please follow these steps with the code sandbox:

Note: This codesandbox is just a basic flexible layout with CSS styles, media queries and basic react components and the bug happens within the Middle.js component.

Code: https://codesandbox.io/s/young-dawn-1x6jx?file=/src/App.js

Steps:

1.) Refresh the page - (The left yellow and right purple sides will randomly disappear after page refresh)
2.) Refresh the page again - (The left yellow and right purple sides will not come back)
3.) Adjust the size of the viewport - (The left yellow and right purple sides will randomly come back)
4.) Remove lines 3,5,6 from file: Middle.js - (The bug stops and it works normally)

What's wrong?: The left yellow and right purple sides should not disappear on refresh.

I have really no idea what's going wrong technically, but I think that this library is conflicting with the media queries or material-ui.

Support individual dimension-tracking and new options interface

For the next release, will be providing a new interface which will be preferred over the previous parameter overloading. Example usage:

// default behavior
const [vpW, vpH] = useViewportSizes({ dimension: 'both' });
// with only one dimension observed, and `debounceTimeout` of `20` ms applied
const vpW = useViewportSizes({ dimension: 'w', debounceTimeout: 20 });

Input-option type:

    export type VPSizesHasher = (({ vpW: number, vpH: number }) => String);
    export type VPSizesOptions ={
        debounceTimeout?: number,
        throttleTimeout?: number,
        hasher?: VPSizesHasher,
        dimension?: 'w'|'h'|'both' = 'both'
    };

The interface will be backwards-compatible, but the default behavior for numbers as input will be to throttle eventually vs debounce as a more natural resize method.

Initially will just default to debounceTimeout behavior, but as a heads up to anyone using the library where it is going and why there may be a major semver version bump.

(input is welcome for anyone interested)

Add Typescript support

Would be great to get typescript inferences -- especially with upcoming throttle interface.

Probably best to go the route of typescript declaration file.

Add Throttle Support and use as default input behavior

Hey, I love this hook, it does just the one thing it's supposed to!

I'd love to throttle the function rather than debounce, would be cool to see the changes while resizing. Now it requires the user to stop.

Would you be willing to put that in if I'd open a PR?

Improve Examples and use new interface

Interface is just about done after a bit more testing. In order to post meaningful documentation, there should be newer examples on Codebase. Would not hurt to make them look a lot nicer.

One idea particularly is to render the viewport sizes themselves on observed changes on CodeSandbox in addition to filled colorings (less-busy looking). Obviously could not do this in both directions at once, but the new dimension option allows the examples to make more sense with component widths/heights changing themselves according to when updates are registered now.

useLayoutEffect warning during SSR

Hey, first off, thanks for this really nifty hook, in particular the focus on performance and avoiding unnecessary re-renders!

I've been using it in a Vite project, and noticed I'm getting a warning during SSR b/c of useLayoutEffect

Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayoutEffect should only be used in components that render exclusively on the client. See https://reactjs.org/link/uselayouteffect-ssr for common fixes.

This warning can be avoided by explicitly using useEffect instead of useLayoutEffect during SSR. Here's one really simple implementation:
https://usehooks-ts.com/react-hook/use-isomorphic-layout-effect

There's no change in behavior (both hooks are skipped during SSR). It's just a way of telling the framework that you know that this won't run on the server and are ok with that.

README.md is out-of-date or incorrect for TypeScript

You cannot call useViewportSizes with no parameters, you get a compilation error.

Further, you cannot get properly typed parameters when you want only width and height, ignoring the triggerResize value. TypeScript assumes you're expecting the other result type which is dimension, triggerResize. Note, using the following causes eslint issues when you really don't want triggerResize and don't use it in subsequent source.

const [vpW, vpH, updateVpSizes] = useViewportSizes(); doSomething(vpW, vpH); // ignore updateVpSizes return; // Error will result because updateVpSizes is unused

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.