• Stars
    star
    214
  • Rank 180,880 (Top 4 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 2 years ago
  • Updated over 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Hook to create multiple refs in a single call

useRefs ♻️

React hook to create multiple refs in a single call.

Usage

Instead of calling useRef many times, you just call useRefs and destructure as many refs as you want!

import useRefs from "react-use-refs";

const [someRef, anotherRef] = useRefs();

The first and only argument is the initialValue of the refs. There’s no way to specify a different value for each ref. Use a list of React.useRefs for that!

TypeScript support

This library supports TypeScript and should work exactly as React.useRef does.

const [cardRef, cardBodyRef] = useRefs<HTMLDivElement>();

return <div ref={cardRef}> ... </div>;

If you want to have multiple ref types, then you can pass a tuple and have it spread onto the created refs:

const [cardRef, inputRef] = useRefs<[HTMLDivElement, HTMLInputElement]>(null);

⚠️ Passing null as the initialValue is required for tuples!

Frequently Asked Questions

🧙‍♀️ Is this black magic?

No. Keep reading.

🤔 So how does this work?!

This hook returns an iterable object, something you can use in a for (of) statement, with Array.from() or (and this is the neat part) with the Array Destructuring syntax (the one you use for state/setState pairs for example.)

Also, if you have a look at the code the returned value from the iterator has always the done flag set to false. This is an infinite loop disguised as an iterator! But since calling next during array destructuring happens a finite number of times, hence we do not hit typical infinte loop behaviour (aka frozen page).

📜 Does this break the Rules of Hooks?

Short answer: no. Real answer: it’s up to you. Actual real answer follows.

The Rules of Hooks section of React’s official documentation cite: Don’t call Hooks inside loops, conditions, or nested functions.

As you can see in the source code we are definitely breaking this rule by calling useRef inside the next() method of the Iterable.

But we need to understand the the Rules of Hooks exist for a reason, and that is to have statically stable invocation of primitive hooks between re-renders.

Since we explicitly encourage the use of Array Destructuring, the dynamic part is made “static” by hard-coding it in your own source code. We therefore do not break the rules of hooks.

😈 But wait I can manually call .next() conditionally!

Yeah, you can do some bad stuff with the returned iterator, but it’s not that different from having, for example, the following code:

const iSwearIAmNotUseRef = React.useRef();

The only issue is that using the returned iterator doesn’t throw a ESLint warning at you as the above code would.

😕 Ok, but why did you do it?

Because I could. And because @drcmda said he would use it and would love it. ❤️ Spread love and not some silly questions about what people do in their free time.

Credits

  • Thanks to @drcmda for stating his need for such an API.
  • Thanks to @Andarist for the initial TypeScript types definition.

License

MIT

More Repositories

1

hooks.macro

☔️ Babel Macros for automatic React Hooks memoization invalidation
JavaScript
357
star
2

react-titanium

React custom renderer for Appcelerator® Titanium™ SDK
JavaScript
108
star
3

TiShimmer

Facebook’s Shimmer port for Titanium SDK (iOS and Android)
Python
31
star
4

Beauvoir

Simple project management app built with node.js
JavaScript
11
star
5

ti-htmlparser2

Forgiving HTML/XML parser for Titanium SDK
JavaScript
7
star
6

java-npm-semver

Implementation of the SemVer Specification — strictly follows npm semantics
Java
6
star
7

hyperloop-macros

Sweet.js macros to accelerate Hyperloop development
JavaScript
6
star
8

frontend-resources-osgi

A discussion about OSGi, Liferay and Front-end
6
star
9

frontend-ng-loader-workspace

Liferay Workspace for experiments in bringing SystemJS and packages support to Liferay Portal
JavaScript
5
star
10

cspec-titanium-packagers-support

CSPEC is for adding official packaging (npm) abilities on Titanium
4
star
11

combinatorial-explosion

Combinatorial explosion for arrays and trees
JavaScript
4
star
12

knockback-site

Knockback.js Site proposal
JavaScript
4
star
13

ti-travis-experiments

Some funny experiments!
JavaScript
3
star
14

postcss-color-mod

PostCSS Polyfill for color-mod() — ⚠️ Experimental
JavaScript
2
star
15

svbstantia

Simple substance-powered Node.js blog platform
JavaScript
2
star
16

underscore.behaviour

Behaviours (execution limiters) extension for Underscore.js javascript library
JavaScript
1
star
17

authograph

Artistic JavaScript signatures.
1
star
18

hyperloop-ejs

Appcelerator’s Hyperloop-oriented EJS Syntax
1
star
19

lris-2015-liferay-7-front-end

Liferay 7 Front-end development
HTML
1
star
20

5cript

Markdown like syntax for theater scripts.
JavaScript
1
star
21

overscore

Underscore.js for hipsters
1
star
22

rosetta

1
star
23

liferay-theme-tasks-fixed

JavaScript
1
star
24

metameric.js

A funny chainable-isation utility
CoffeeScript
1
star
25

titanium-platforms

Titanium™ SDK utils for device conditional code
JavaScript
1
star
26

lrbcr-2018-audience-targeting-mocked-service

JavaScript
1
star
27

smc-image-placer

JavaScript
1
star
28

it_IT

Versione italiana del mio blog personale
1
star
29

lris-2016-metaljs-and-isomorphic-frontend

Metal.js, Soy and Isomorphic Front-end
Java
1
star
30

decorators-toolbox

A Toolbox for writing ES7 decorators more easily
JavaScript
1
star
31

ti-cross-ci-experiments

Experiments in the CI land for cross-platform projects
JavaScript
1
star
32

spid-cie-oidc-django

The SPID/CIE OIDC Federation SDK, written in Python
Python
1
star