Git Product home page Git Product logo

react-hooks's Introduction

@kripod/react-hooks

Essential set of React Hooks for convenient Web API consumption and state management.

Travis (.com) Language grade: JavaScript Codecov Commitizen friendly lerna

Key features

  • 🌳 Bundler-friendly with tree shaking support
  • πŸ“š Well-documented and type-safe interfaces
  • βš›οΈ Zero-config server-side rendering capability
  • πŸ“¦ Self-contained, free of runtime dependencies

Project structure

Being composed of multiple packages, this project is managed as a monorepo. Please see the documentation of each package for further details about them:

Contributing

Thanks for being interested in contributing! Please read our contribution guidelines to get started.

Contributors ✨

Thanks goes to these wonderful people (emoji key):


KristΓ³f PoduszlΓ³

🚧 πŸ’» ⚠️ πŸ“– πŸ’‘ πŸ€” πŸš‡

Dan Abramov

πŸ’» πŸ“ πŸ€” βœ…

Donavon West

⚠️

Prasanna Mishra

πŸ“–

Nolansym

πŸ’‘

Charles Moog

πŸ’» ⚠️ πŸ“– πŸ’‘

Michael Jackson

πŸ€”

Jose Felix

πŸš‡ πŸ’»

Davide Gheri

πŸ›

This project follows the all-contributors specification. Contributions of any kind welcome!

react-hooks's People

Contributors

allcontributors[bot] avatar dependabot-preview[bot] avatar dependabot[bot] avatar kripod 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-hooks's Issues

Implement Visual Viewport API

Motivation

Sometimes, classic scrollbars and on-screen keyboards shall be excluded when calculating the dimensions of a document.

Details

  • Visual Viewport API specification
  • Add useViewportScrollCoords, useViewportSize and useViewportScale hooks
  • Keep useWindowScrollCoords and useWindowSize hooks, optionally updating their docs to emphasize which elements are included in the results

Add `useMedia` hook

Motivation

Track whether a document matches the given media query. This may also be used for a usePreferredColorScheme (or useDarkMode) hook.

Basic example

const isDesktop = useMedia('(min-width: 1024px)');

Details

TypeScript error: Cannot find name 'NetworkInformation'. TS2304

I am getting this error.

TypeScript error: Cannot find name 'NetworkInformation'.  TS2304
    15 |  * }
    16 |  */
  > 17 | export default function useNetworkInformation(): NetworkInformation | undefined;
       |                                                  ^
    18 | 

My tsconfig.json is this:

{
	"compilerOptions": {
		"baseUrl": "src",
		"outDir": "build",
		"module": "commonjs",
		"lib": [ "es6", "dom" ],
		"allowJs": true,
		"jsx": "react",
		"moduleResolution": "node",
		"rootDir": "src",
	},
	"exclude": [
		"build",
		"config",
		"node_modules",
		"scripts"
	],
	"include": [ "src" ],
	"types": [
		"typePatches"
	]
}

Rename the project due to popular demand

As discussed on Reddit, the word "standard" may confuse some users:

Seeing the word "standard" in the name gives me flashbacks of the so-called "standard" config for ESLint which was not at all standard and quite opinionated in parts. – qeBhuajX5JAooqbRNiNv

I am open towards further discussion, listening to any viable alternatives which would eliminate bad feelings related to branding. The only requirement is that the name has to be generic enough to cover all the aspects of the library.

Add `useClipboard` hook

Motivation

When it comes to interacting with the clipboard, multiple options are available. The Clipboard API is not yet widely supported by browsers.

A compatible solution should be available out of the box:

Basic example

function Example() {
  const { copy, cut, paste } = useClipboard();
  const [value, setValue] = useState('foo');

  return (
    <>
      <input value={value} onChange={(e) => setValue(e.target.value)} />
      <button type="button" onClick={() => copy(value)}>Copy</button>
    </>
  );
}

Details

Lack of permissions (e.g. for pasting) should be handled gracefully with opt-in support for error callbacks.

Design branding assets

This project needs a logo of its own. It would be displayed in the readme and as a 1280Γ—640px social media preview.

Personally, I was thinking about an anchor icon representing a hook, with "standard-hooks" written next to it. The project's name may be broken into two lines, making the use of "-" optional.

[useMedia | usePreferredColorScheme] Not working on Safari

Description

The useMedia (and usePreferredColorScheme, since it uses useMedia) hook doesn't work on Safari, either MacOS and iOS.
This is because the MediaQueryList interface on Safari doesn't inherit any methods from EventTarget, and because of that not exposing addEventListener and removeEventListener methods.

Since the util managedEventListener is used widely in the library, I think we should create a new specific function to handle this "edge" case, that just checks if target.addListener / target.removeListener are functions and call them instead of add/removeEventListener

Reproduction

use useMedia hook on Safari, the console should log:
TypeError: target.addEventListener is not a function. (In 'target.addEventListener(type, callback, options)', 'target.addEventListener' is undefined)

Environment

System:

  • OS: macOS Mojave 10.14.4
  • CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
  • Memory: 35.11 MB / 16.00 GB
  • Shell: 5.3 - /bin/zsh

Binaries:

  • Node: 10.16.3 - ~/.nvm/versions/node/v10.16.3/bin/node
  • Yarn: 1.17.3 - /usr/local/bin/yarn
  • npm: 6.9.0 - ~/.nvm/versions/node/v10.16.3/bin/npm
  • Watchman: 4.9.0 - /usr/local/bin/watchman

Browsers:

  • Chrome: 77.0.3865.120
  • Firefox: 69.0.3
  • Safari: 12.1

npmPackages:

  • react: ^16.9.0 => 16.10.2
  • web-api-hooks: ^2.0.0 => 2.0.0

Add `useEvictingQueue` middleware for keeping track of last N array state items

Motivation

Arrays used as state variables may have a desired length limit. The EvictingQueue data structure was just made with this purpose in mind. Encapsulating it in a hook as a middleware would allow its usage with any kind of state-returning functions (e.g. useState or even useLocalStorage).

Basic example

function Example() {
  const chatMessages = useEvictingQueue(100, useState<string[]>([]));
}

Details

Basic implementation idea:

import { useCallback } from 'react';

export default function useEvictingQueue<T>(
  maxLength: number,
  [value, setValue]: [T[], React.Dispatch<React.SetStateAction<T[]>>],
) {
  const newSetValue = useCallback(
    (update: React.SetStateAction<T[]>) => {
      setValue(prevValue => {
        const nextValue =
          typeof update === 'function' ? update(prevValue) : update;
        return nextValue.length > maxLength
          ? nextValue.slice(nextValue.length - maxLength)
          : nextValue;
      });
    },
    [maxLength, setValue],
  );

  return [value, newSetValue];
}

Add hook for measuring components

Motivation

One may need to know the exact size of a DOM node, to know whether it's big or small enough.

Details

How can I measure a DOM node? – React Hooks FAQ:

function MeasureExample() {
  const [rect, ref] = useClientRect();
  return (
    <>
      <h1 ref={ref}>Hello, world</h1>
      {rect !== null &&
        <h2>The above header is {Math.round(rect.height)}px tall</h2>
      }
    </>
  );
}

function useClientRect() {
  const [rect, setRect] = useState(null);
  const ref = useCallback(node => {
    if (node !== null) {
      setRect(node.getBoundingClientRect());
    }
  }, []);
  return [rect, ref];
}

`useLocalStorage` not updating if many components watch the same key

Description

Hey! Thanks for the awesome project. I’m having a problem where multiple calls to useLocalStorage('my-key') from different components are not staying in sync as the value changes.

Reproduction

I’ve reproduced it in this sandbox:

https://codesandbox.io/s/distracted-bash-x9k10?file=/pages/index.js

Expected behavior

If my localStorage value changes, all my components watching that value pick up the change.

Actual behavior

The hook seems to be initializing from localStorage into individual instances of useState and then never reading from localStorage again.

Website-based documentation with interactive examples

Motivation

Being readme-embedded, the documentation is starting to get cluttered and incomprehensible. Interactive playgrounds and use-cases should be provided for each hook and their configurable parameters.

Details

For example, Chakra UI provides concise and comprehensible docs for their components, packed with editable examples usable out of the box.

A similar approach is desired for standard-hooks, while keeping JSDoc comments in sync with the ones on the web, preferably with automation.

Add `useCounter` wrapper hook with increment and decrement methods

Motivation

Pagination components rely upon counters. This hook wraps a state-returning hook and appends increment and decrement functionality to the returned tuple.

Basic example

function Example() {
  const [page, setPage, incrementPage, decrementPage] = useCounter(
    useState(1),
    1, // minValue
    100, // maxValue
  );
}

Details

  • minValue and maxValue shall have no effect on behavior unless specified explicitly
  • Increment and decrement functions should have an optional "by" parameter, defaulting to 1

[useToggle] Rewrite as a wrapper hook

Motivation

While the current implementation of useToggle handles a given state variable specially, wrapper syntax would allow it to control custom states (e.g. the one returned by useLocalStorage).

Basic example

function Example() {
  const [isPressed, togglePressed] = useToggle(useLocalStorage('isPressed', false));
}

Add `usePreferredColorScheme` hook

Motivation

Dark mode is getting increasingly popular. Developers may want to track the color scheme preference of users.

Basic example

const preferredColorScheme = usePreferredColorScheme();

Details

  • Depends on useMedia (#9)

Add husky for format and lint before commit

Motivation

Since the contributor has to run yarn format and yarn lint before committing, this can result in someone committing without running both of these. We could add husky to handle this for us automatically and ensure commits are correct in terms of format and lint before code review in PR.

Basic example

Just by git commit -m "MESSAGE" the code would be linted and formatted.

Add `usePrevious` hook

Motivation

Sometimes, the previous value of a variable may be needed through subsequent re-renders.

Basic example

function Counter() {
  const [count, setCount] = useState(0);
  const prevCount = usePrevious(count);
  return <h1>Now: {count}, before: {prevCount}</h1>;
}

Details

How to get the previous props or state? – React Hooks FAQ:

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
}

error Object(...) is not a function

Description

using useSize I get the following error in a Typescript setup:
Object(...) is not a function

Reproduction

const imageRef = useRef(null);
const [width, height] = useSize(imageRef);
return <img ref={imageRef} srcSet={`${src} 1x`} src={src} />;

Expected behavior

There should be no error

Actual behavior

adding the line with useSize results in the above error, without everything is working

Environment

Not sure if this works properly:

System:

  • OS: macOS High Sierra 10.13.6
  • CPU: (4) x64 Intel(R) Core(TM) i5-4258U CPU @ 2.40GHz
  • Memory: 135.68 MB / 16.00 GB
  • Shell: 3.2.57 - /bin/bash

Binaries:

  • Node: 14.15.4 - /usr/local/bin/node
  • Yarn: 1.22.5 - ~/.yarn/bin/yarn
  • npm: 6.14.10 - /usr/local/bin/npm

Browsers:

  • Chrome: 89.0.4389.90
  • Firefox: 86.0
  • Safari: 13.1.2

React: 16.3.1,
web-api-hooks: "^3.0.2",

Add `useTimeline` hook for tracking multiple previous values

Motivation

usePrevious (#18) can be used to retrieve the last single previous value of a variable. A useTimeline hook would make it possible to track the last N different values of a given value, useful for keeping a log of changes.

Basic example

function Counter() {
  const [count, setCount] = useState(0);
  const prevCounts = useTimeline(count);
  return <h1>Now: {count}, history: {prevCounts}</h1>;
}

After increasing the count variable 3 times, the result would be:

Now: 3, history: [0, 1, 2]

The difference between useTimeline and usePrevious is that the value of useTimeline changes only when there was no bailout of a state update.

Details

In order to avoid storing too much values, useTimeline should have a parameter to limit the amount of stored values, defaulting to Number.MAX_SAFE_INTEGER.

Add a state hook for change detection over a period of time

Motivation

Inspired by useScrolling of react-use, a generic state wrapper hook (useChanging?) could be added with an optionally specifiable maximum delay between changes.

Basic example

const windowSize = useWindowSize();

// If the value of `windowSize` changes at least every 150ms,
// then `isWindowSizeChanging` should be `true`
const isWindowSizeChanging = useChanging(windowSize, 150);

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.