You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 7-8.RSVP
Socket
Socket
Sign inDemoInstall

@reach/auto-id

Package Overview
Dependencies
Maintainers
3
Versions
46
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.5.3 to 0.6.1

src/index.test.js

82

es/index.js

@@ -1,7 +0,46 @@

import { useState, useEffect } from "react"; // Could use UUID but if we hit 9,007,199,254,740,991 unique components over
// the lifetime of the app before it gets reloaded, I mean ... come on.
// I don't even know what xillion that is.
// /me googles
// Oh duh, quadrillion. Nine quadrillion components. I think we're okay.
/*
* Let's see if we can make sense of why this hook exists and its
* implementation.
*
* Some background:
* 1. Accessibiliy APIs rely heavily on element IDs
* 2. Requiring developers to put IDs on every element in Reach UI is both
* cumbersome and error-prone
* 3. With a component model, we can generate IDs for them!
*
* Solution 1: Generate random IDs.
*
* This works great as long as you don't server render your app. When React (in
* the client) tries to reuse the markup from the server, the IDs won't match
* and React will then recreate the entire DOM tree.
*
* Solution 2: Increment an integer
*
* This sounds great. Since we're rendering the exact same tree on the server
* and client, we can increment a counter and get a deterministic result between
* client and server. Also, JS integers can go up to nine-quadrillion. I'm
* pretty sure the tab will be closed before an app never needs
* 10 quadrillion IDs!
*
* Problem solved, right?
*
* Ah, but there's a catch! React's concurrent rendering makes this approach
* non-deterministic. While the client and server will end up with the same
* elements in the end, depending on suspense boundaries (and possibly some user
* input during the initial render) the incrementing integers won't always match
* up.
*
* Solution 3: Don't use IDs at all on the server; patch after first render.
*
* What we've done here is solution 2 with some tricks. With this approach, the
* ID returned is an empty string on the first render. This way the server and
* client have the same markup no matter how wild the concurrent rendering may
* have gotten.
*
* After the render, we patch up the components with an incremented ID. It
* doesn't have to be incremented, though; we could do something random, but
* incrementing a number is probably the cheapest thing we can do.
*/
import { useState, useEffect, useLayoutEffect } from "react";
var serverHandoffComplete = false;
var id = 0;

@@ -13,11 +52,36 @@

export var useId = function useId() {
var _useState = useState(null),
export var useId = function useId(fallback) {
/*
* If this instance isn't part of the initial render, we don't have to do the
* double render/patch-up dance. We can just generate the ID and return it.
*/
var initialId = fallback || (serverHandoffComplete ? genId() : null);
var _useState = useState(initialId),
id = _useState[0],
setId = _useState[1];
useLayoutEffect(function () {
if (id === null) {
/*
* Patch the ID after render. We do this in `useLayoutEffect` to avoid any
* rendering flicker, though it'll make the first render slower (unlikely
* to matter, but you're welcome to measure your app and let us know if
* it's a problem).
*/
setId(genId());
} // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(function () {
return setId(genId());
if (serverHandoffComplete === false) {
/*
* Flag all future uses of `useId` to skip the update dance. This is in
* `useEffect` because it goes after `useLayoutEffect`, ensuring we don't
* accidentally bail out of the patch-up dance prematurely.
*/
serverHandoffComplete = true;
}
}, []);
return id;
};

2

index.d.ts

@@ -10,2 +10,2 @@ /**

*/
export const useId: () => number;
export const useId: (hasFallback?: string) => number;

@@ -8,7 +8,46 @@ "use strict";

// Could use UUID but if we hit 9,007,199,254,740,991 unique components over
// the lifetime of the app before it gets reloaded, I mean ... come on.
// I don't even know what xillion that is.
// /me googles
// Oh duh, quadrillion. Nine quadrillion components. I think we're okay.
/*
* Let's see if we can make sense of why this hook exists and its
* implementation.
*
* Some background:
* 1. Accessibiliy APIs rely heavily on element IDs
* 2. Requiring developers to put IDs on every element in Reach UI is both
* cumbersome and error-prone
* 3. With a component model, we can generate IDs for them!
*
* Solution 1: Generate random IDs.
*
* This works great as long as you don't server render your app. When React (in
* the client) tries to reuse the markup from the server, the IDs won't match
* and React will then recreate the entire DOM tree.
*
* Solution 2: Increment an integer
*
* This sounds great. Since we're rendering the exact same tree on the server
* and client, we can increment a counter and get a deterministic result between
* client and server. Also, JS integers can go up to nine-quadrillion. I'm
* pretty sure the tab will be closed before an app never needs
* 10 quadrillion IDs!
*
* Problem solved, right?
*
* Ah, but there's a catch! React's concurrent rendering makes this approach
* non-deterministic. While the client and server will end up with the same
* elements in the end, depending on suspense boundaries (and possibly some user
* input during the initial render) the incrementing integers won't always match
* up.
*
* Solution 3: Don't use IDs at all on the server; patch after first render.
*
* What we've done here is solution 2 with some tricks. With this approach, the
* ID returned is an empty string on the first render. This way the server and
* client have the same markup no matter how wild the concurrent rendering may
* have gotten.
*
* After the render, we patch up the components with an incremented ID. It
* doesn't have to be incremented, though; we could do something random, but
* incrementing a number is probably the cheapest thing we can do.
*/
var serverHandoffComplete = false;
var id = 0;

@@ -20,9 +59,34 @@

var useId = function useId() {
var _useState = (0, _react.useState)(null),
var useId = function useId(fallback) {
/*
* If this instance isn't part of the initial render, we don't have to do the
* double render/patch-up dance. We can just generate the ID and return it.
*/
var initialId = fallback || (serverHandoffComplete ? genId() : null);
var _useState = (0, _react.useState)(initialId),
id = _useState[0],
setId = _useState[1];
(0, _react.useLayoutEffect)(function () {
if (id === null) {
/*
* Patch the ID after render. We do this in `useLayoutEffect` to avoid any
* rendering flicker, though it'll make the first render slower (unlikely
* to matter, but you're welcome to measure your app and let us know if
* it's a problem).
*/
setId(genId());
} // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
(0, _react.useEffect)(function () {
return setId(genId());
if (serverHandoffComplete === false) {
/*
* Flag all future uses of `useId` to skip the update dance. This is in
* `useEffect` because it goes after `useLayoutEffect`, ensuring we don't
* accidentally bail out of the patch-up dance prematurely.
*/
serverHandoffComplete = true;
}
}, []);

@@ -29,0 +93,0 @@ return id;

{
"name": "@reach/auto-id",
"version": "0.5.3",
"version": "0.6.1",
"description": "Autogenerate IDs to facilitate WAI-ARIA and server rendering.",

@@ -23,3 +23,3 @@ "main": "index.js",

],
"gitHead": "29e599938054fd0601f347f66d8671e690ecf879"
"gitHead": "c1e249448a3672ccc65698218f0f38ef9814ab90"
}

@@ -1,15 +0,84 @@

import { useState, useEffect } from "react";
/*
* Let's see if we can make sense of why this hook exists and its
* implementation.
*
* Some background:
* 1. Accessibiliy APIs rely heavily on element IDs
* 2. Requiring developers to put IDs on every element in Reach UI is both
* cumbersome and error-prone
* 3. With a component model, we can generate IDs for them!
*
* Solution 1: Generate random IDs.
*
* This works great as long as you don't server render your app. When React (in
* the client) tries to reuse the markup from the server, the IDs won't match
* and React will then recreate the entire DOM tree.
*
* Solution 2: Increment an integer
*
* This sounds great. Since we're rendering the exact same tree on the server
* and client, we can increment a counter and get a deterministic result between
* client and server. Also, JS integers can go up to nine-quadrillion. I'm
* pretty sure the tab will be closed before an app never needs
* 10 quadrillion IDs!
*
* Problem solved, right?
*
* Ah, but there's a catch! React's concurrent rendering makes this approach
* non-deterministic. While the client and server will end up with the same
* elements in the end, depending on suspense boundaries (and possibly some user
* input during the initial render) the incrementing integers won't always match
* up.
*
* Solution 3: Don't use IDs at all on the server; patch after first render.
*
* What we've done here is solution 2 with some tricks. With this approach, the
* ID returned is an empty string on the first render. This way the server and
* client have the same markup no matter how wild the concurrent rendering may
* have gotten.
*
* After the render, we patch up the components with an incremented ID. It
* doesn't have to be incremented, though; we could do something random, but
* incrementing a number is probably the cheapest thing we can do.
*/
// Could use UUID but if we hit 9,007,199,254,740,991 unique components over
// the lifetime of the app before it gets reloaded, I mean ... come on.
// I don't even know what xillion that is.
// /me googles
// Oh duh, quadrillion. Nine quadrillion components. I think we're okay.
import { useState, useEffect, useLayoutEffect } from "react";
let serverHandoffComplete = false;
let id = 0;
const genId = () => ++id;
export const useId = () => {
const [id, setId] = useState(null);
useEffect(() => setId(genId()), []);
export const useId = fallback => {
/*
* If this instance isn't part of the initial render, we don't have to do the
* double render/patch-up dance. We can just generate the ID and return it.
*/
const initialId = fallback || (serverHandoffComplete ? genId() : null);
const [id, setId] = useState(initialId);
useLayoutEffect(() => {
if (id === null) {
/*
* Patch the ID after render. We do this in `useLayoutEffect` to avoid any
* rendering flicker, though it'll make the first render slower (unlikely
* to matter, but you're welcome to measure your app and let us know if
* it's a problem).
*/
setId(genId());
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
if (serverHandoffComplete === false) {
/*
* Flag all future uses of `useId` to skip the update dance. This is in
* `useEffect` because it goes after `useLayoutEffect`, ensuring we don't
* accidentally bail out of the patch-up dance prematurely.
*/
serverHandoffComplete = true;
}
}, []);
return id;
};
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc