Socket
Socket
Sign inDemoInstall

use-callback-ref

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

use-callback-ref - npm Package Compare versions

Comparing version 1.3.0 to 1.3.1

27

dist/es2015/useMergeRef.js

@@ -0,3 +1,5 @@

import * as React from 'react';
import { assignRef } from './assignRef';
import { useCallbackRef } from './useRef';
var currentValues = new WeakMap();
/**

@@ -18,3 +20,26 @@ * Merges two or more refs together providing a single interface to set their value

export function useMergeRefs(refs, defaultValue) {
return useCallbackRef(defaultValue || null, function (newValue) { return refs.forEach(function (ref) { return assignRef(ref, newValue); }); });
var callbackRef = useCallbackRef(defaultValue || null, function (newValue) {
return refs.forEach(function (ref) { return assignRef(ref, newValue); });
});
// handle refs changes - added or removed
React.useLayoutEffect(function () {
var oldValue = currentValues.get(callbackRef);
if (oldValue) {
var prevRefs_1 = new Set(oldValue);
var nextRefs_1 = new Set(refs);
var current_1 = callbackRef.current;
prevRefs_1.forEach(function (ref) {
if (!nextRefs_1.has(ref)) {
assignRef(ref, null);
}
});
nextRefs_1.forEach(function (ref) {
if (!prevRefs_1.has(ref)) {
assignRef(ref, current_1);
}
});
}
currentValues.set(callbackRef, refs);
}, [refs]);
return callbackRef;
}

@@ -0,3 +1,5 @@

import * as React from 'react';
import { assignRef } from './assignRef';
import { useCallbackRef } from './useRef';
const currentValues = new WeakMap();
/**

@@ -18,3 +20,24 @@ * Merges two or more refs together providing a single interface to set their value

export function useMergeRefs(refs, defaultValue) {
return useCallbackRef(defaultValue || null, (newValue) => refs.forEach((ref) => assignRef(ref, newValue)));
const callbackRef = useCallbackRef(defaultValue || null, (newValue) => refs.forEach((ref) => assignRef(ref, newValue)));
// handle refs changes - added or removed
React.useLayoutEffect(() => {
const oldValue = currentValues.get(callbackRef);
if (oldValue) {
const prevRefs = new Set(oldValue);
const nextRefs = new Set(refs);
const current = callbackRef.current;
prevRefs.forEach((ref) => {
if (!nextRefs.has(ref)) {
assignRef(ref, null);
}
});
nextRefs.forEach((ref) => {
if (!prevRefs.has(ref)) {
assignRef(ref, current);
}
});
}
currentValues.set(callbackRef, refs);
}, [refs]);
return callbackRef;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useMergeRefs = void 0;
var tslib_1 = require("tslib");
var React = tslib_1.__importStar(require("react"));
var assignRef_1 = require("./assignRef");
var useRef_1 = require("./useRef");
var currentValues = new WeakMap();
/**

@@ -21,4 +24,27 @@ * Merges two or more refs together providing a single interface to set their value

function useMergeRefs(refs, defaultValue) {
return (0, useRef_1.useCallbackRef)(defaultValue || null, function (newValue) { return refs.forEach(function (ref) { return (0, assignRef_1.assignRef)(ref, newValue); }); });
var callbackRef = (0, useRef_1.useCallbackRef)(defaultValue || null, function (newValue) {
return refs.forEach(function (ref) { return (0, assignRef_1.assignRef)(ref, newValue); });
});
// handle refs changes - added or removed
React.useLayoutEffect(function () {
var oldValue = currentValues.get(callbackRef);
if (oldValue) {
var prevRefs_1 = new Set(oldValue);
var nextRefs_1 = new Set(refs);
var current_1 = callbackRef.current;
prevRefs_1.forEach(function (ref) {
if (!nextRefs_1.has(ref)) {
(0, assignRef_1.assignRef)(ref, null);
}
});
nextRefs_1.forEach(function (ref) {
if (!prevRefs_1.has(ref)) {
(0, assignRef_1.assignRef)(ref, current_1);
}
});
}
currentValues.set(callbackRef, refs);
}, [refs]);
return callbackRef;
}
exports.useMergeRefs = useMergeRefs;

18

package.json
{
"name": "use-callback-ref",
"version": "1.3.0",
"version": "1.3.1",
"description": "The same useRef, but with callback",

@@ -33,10 +33,11 @@ "main": "dist/es5/index.js",

"devDependencies": {
"@theuiteam/lib-builder": "^0.1.4",
"@size-limit/preset-small-lib": "^2.1.6",
"@types/enzyme-adapter-react-16": "^1.0.6",
"enzyme-adapter-react-16": "^1.15.6"
"@testing-library/jest-dom": "^6.1.5",
"@testing-library/react": "^14.1.2",
"@theuiteam/lib-builder": "^0.3.0",
"jest-environment-jsdom": "^29.7.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0"
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
},

@@ -56,5 +57,6 @@ "peerDependenciesMeta": {

"react",
"hoot",
"hook",
"useRef",
"createRef"
"createRef",
"merge refs"
],

@@ -61,0 +63,0 @@ "husky": {

@@ -20,36 +20,44 @@ <div align="center">

> Keep in mind that useRef doesn't notify you when its content changes.
Mutating the .current property doesn't cause a re-render.
If you want to run some code when React attaches or detaches a ref to a DOM node,
you may want to use ~~a callback ref instead~~ .... __useCallbackRef__ instead.
> Mutating the .current property doesn't cause a re-render.
> If you want to run some code when React attaches or detaches a ref to a DOM node,
> you may want to use ~~a callback ref instead~~ .... **useCallbackRef** instead.
– [Hooks API Reference](https://reactjs.org/docs/hooks-reference.html#useref)
Read more about `use-callback` pattern and use cases:
Read more about `use-callback` pattern and use cases:
- https://dev.to/thekashey/the-same-useref-but-it-will-callback-8bo
This library exposes helpers to handle any case related to `ref` _lifecycle_
- `useCallbackRef` - react on hook change
- `mergeRefs` - merge multiple refs together. For, actually, fork
- `transformRef` - transform one ref to anther
- `refToCallback` - convert RefObject to an old callback-style ref
- `assignRef` - assign value to the ref, regardless of it's form
- `useCallbackRef` - react on a ref change (replacement for `useRef`)
- `createCallbackRef` - - low level version of `useCallbackRef`
- `useMergeRefs` - merge multiple refs together creating a stable return ref
- `mergeRefs` - low level version of `useMergeRefs`
- `useTransformRef` - transform one ref to another (replacement for `useImperativeHandle`)
- `transformRef` - low level version of `useTransformRef`
- `useRefToCallback` - convert RefObject to an old callback-style ref
- `refToCallback` - low level version of `useRefToCallback`
- `assignRef` - assign value to the ref, regardless it is RefCallback or RefObject
All functions are tree shakable, but even together it's __less then 300b__.
All functions are tree shakable, but even together it's **less then 300b**.
# API
💡 Some commands are hooks based, and returns the same refs/functions every render.
💡 Some commands are hooks based, and returns the same refs/functions every render.
But some are not, to be used in classes or non-react code.
## useRef API
🤔 Use case: every time you have to react to ref change
API is 99% compatible with React `createRef` and `useRef`, and just adds another argument - `callback`,
which would be called on __ref update__.
which would be called on **ref update**.
#### createCallbackRef - to replace React.createRef
- `createCallbackRef(callback)` - would call provided `callback` when ref is changed.
- `createCallbackRef(callback)` - would call provided `callback` when ref is changed.
#### useCallbackRef - to replace React.useRef
- `useCallbackRef(initialValue, callback)` - would call provided `callback` when ref is changed.

@@ -60,23 +68,24 @@

```js
import {useRef, createRef, useState} from 'react';
import {useCallbackRef, createCallbackRef} from 'use-callback-ref';
import { useRef, createRef, useState } from 'react';
import { useCallbackRef, createCallbackRef } from 'use-callback-ref';
const Component = () => {
const [,forceUpdate] = useState();
const [, forceUpdate] = useState();
// I dont need callback when ref changes
const ref = useRef(null);
const ref = useRef(null);
// but sometimes - it could be what you need
const anotherRef = useCallbackRef(null, () => forceUpdate());
useEffect( () => {
useEffect(() => {
// now it's just possible
}, [anotherRef.current]) // react to dom node change
}
}, [anotherRef.current]); // react to dom node change
};
```
💡 You can use `useCallbackRef` to convert RefObject into RefCallback, creating bridges between the old and the new code
```js
// some old component
const onRefUpdate = (newValue) => {...}
const onRefUpdate = (newRef) => {...}
const refObject = useCallbackRef(null, onRefUpdate);

@@ -88,2 +97,3 @@ // ...

## assignRef
🤔 Use case: every time you need to assign ref manually, and you dont know the shape of the ref

@@ -98,7 +108,8 @@

import {assignRef} from "use-callback-ref";
✅ assignRef(ref, value);
✅ assignRef(ref, value);
```
## useTransformRef (to replace React.useImperativeHandle)
🤔 Use case: ref could be different.
🤔 Use case: ref could be different.
`transformRef(ref, tranformer):Ref` - return a new `ref` which would propagate all changes to the provided `ref` with applied `transform`

@@ -108,18 +119,18 @@

// before
const ResizableWithRef = forwardRef((props, ref) =>
<Resizable {...props} ref={i => i && ref(i.resizable)}/>
);
const ResizableWithRef = forwardRef((props, ref) => <Resizable {...props} ref={(i) => i && ref(i.resizable)} />);
// after
const ResizableWithRef = forwardRef((props, ref) =>
<Resizable {...props} ref={transformRef(ref, i => i ? i.resizable : null)}/>
);
const ResizableWithRef = forwardRef((props, ref) => (
<Resizable {...props} ref={transformRef(ref, (i) => (i ? i.resizable : null))} />
));
```
## refToCallback
`refToCallback(ref: RefObject): RefCallback` - for compatibility between the old and the new code.
For the compatibility between `RefCallback` and RefObject use `useCallbackRef(undefined, callback)`
For the compatibility between `RefCallback` and RefObject use `useCallbackRef(undefined, callback)`
## useMergeRefs
`mergeRefs(refs: arrayOfRefs, [defaultValue]):ReactMutableRef` - merges a few refs together

@@ -130,4 +141,4 @@

```js
import React from 'react'
import {useMergeRefs} from 'use-callback-ref'
import React from 'react';
import { useMergeRefs } from 'use-callback-ref';

@@ -138,4 +149,4 @@ const MergedComponent = React.forwardRef((props, ref) => {

// both localRef and ref would be populated with the `ref` to a `div`
return <div ref={useMergeRefs([localRef, ref])} />
})
return <div ref={useMergeRefs([localRef, ref])} />;
});
```

@@ -145,3 +156,4 @@

## mergeRefs
## mergeRefs
`mergeRefs(refs: arrayOfRefs, [defaultValue]):ReactMutableRef` - merges a few refs together

@@ -152,5 +164,6 @@ is a non-hook based version. Will produce the new `ref` every run, causing the old one to unmount, and be _populated_ with the `null` value.

`mergeRefs` are "safe" to use as a part of other hooks-based commands, but don't forget - it returns a new object every call.
`mergeRefs` are "safe" to use as a part of other hooks-based commands, but don't forget - it returns a new object every call.
# Similar packages:
- [apply-ref](https://github.com/mitchellhamilton/apply-ref) - `applyRefs` is simular to `mergeRef`, `applyRef` is similar to `assignRef`

@@ -165,3 +178,3 @@ - [useForkRef](https://react-hooks.org/docs/use-fork-ref) - `useForkRef` is simular to `useMergeRefs`, but accepts only two arguments.

# License
MIT
SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc