Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
use-callback-ref
Advanced tools
The use-callback-ref npm package provides React hooks for creating and managing callback refs in a more convenient and powerful way. It allows for the creation of refs that can execute a callback function whenever the ref changes, enabling more reactive and dynamic interactions with DOM elements or component instances in React applications.
Creating a callback ref
This feature allows the creation of a callback ref that executes a callback function whenever the ref's current element changes. In this example, the callback updates the state with the height of the element.
import { useCallbackRef } from 'use-callback-ref';
const MyComponent = () => {
const [height, setHeight] = useState(0);
const ref = useCallbackRef(null, (element) => {
if (element !== null) {
setHeight(element.getBoundingClientRect().height);
}
});
return <div ref={ref}>Content</div>;
};
Using a callback ref with useEffect
This demonstrates how to use a callback ref in conjunction with useEffect to perform actions whenever the ref's current element changes. The callback ref updates a state variable, which triggers the useEffect hook.
import { useCallbackRef } from 'use-callback-ref';
import { useEffect } from 'react';
const MyComponent = () => {
const [node, setNode] = useState(null);
const ref = useCallbackRef(null, setNode);
useEffect(() => {
if (node) {
// Perform actions with the node
}
}, [node]);
return <div ref={ref}>Content</div>;
};
The react-use library is a collection of essential React hooks. It includes a wide variety of hooks for different purposes, including some that can be used to achieve similar functionality to use-callback-ref, such as managing refs and executing effects based on ref changes. However, react-use offers a broader scope of hooks beyond just managing callback refs.
use-referee is a smaller, more focused package that provides hooks for managing refs in React, similar to use-callback-ref. It offers a straightforward approach to creating and managing refs, but it might not have the same level of customization or additional features found in use-callback-ref.
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.
Read more about use-callback
pattern and use cases:
This library exposes helpers to handle any case related to ref
lifecycle
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 RefObjectAll functions are tree shakable, but even together it's less then 300b.
💡 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.
🤔 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.
createCallbackRef(callback)
- would call provided callback
when ref is changed.useCallbackRef(initialValue, callback)
- would call provided callback
when ref is changed.
callback
in both cases iscallback(newValue, oldValue)
. Callback would not be called if newValue and oldValue is the same.
import { useRef, createRef, useState } from 'react';
import { useCallbackRef, createCallbackRef } from 'use-callback-ref';
const Component = () => {
const [, forceUpdate] = useState();
// I dont need callback when ref changes
const ref = useRef(null);
// but sometimes - it could be what you need
const anotherRef = useCallbackRef(null, () => forceUpdate());
useEffect(() => {
// now it's just possible
}, [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
// some old component
const onRefUpdate = (newRef) => {...}
const refObject = useCallbackRef(null, onRefUpdate);
// ...
<SomeNewComponent ref={refObject}/>
🤔 Use case: every time you need to assign ref manually, and you dont know the shape of the ref
assignRef(ref, value)
- assigns values
to the ref
. ref
could be RefObject or RefCallback.
🚫 ref.current = value // what if it's a callback-ref?
🚫 ref(value) // but what if it's a object ref?
import {assignRef} from "use-callback-ref";
✅ assignRef(ref, value);
🤔 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
// before
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))} />
));
refToCallback(ref: RefObject): RefCallback
- for compatibility between the old and the new code.
For the compatibility between RefCallback
and RefObject use useCallbackRef(undefined, callback)
mergeRefs(refs: arrayOfRefs, [defaultValue]):ReactMutableRef
- merges a few refs together
When developing low level UI components, it is common to have to use a local ref but also support an external one using React.forwardRef. Natively, React does not offer a way to set two refs inside the ref property. This is the goal of this small utility.
import React from 'react';
import { useMergeRefs } from 'use-callback-ref';
const MergedComponent = React.forwardRef((props, ref) => {
const localRef = React.useRef();
// ...
// both localRef and ref would be populated with the `ref` to a `div`
return <div ref={useMergeRefs([localRef, ref])} />;
});
💡 - useMergeRefs
will always give you the same return, and you don't have to worry about [localRef, ref]
unique every render.
mergeRefs(refs: arrayOfRefs, [defaultValue]):ReactMutableRef
- merges a few refs together
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 based on https://github.com/smooth-code/react-merge-refs, just exposes a RefObject, instead of a callback
mergeRefs
are "safe" to use as a part of other hooks-based commands, but don't forget - it returns a new object every call.
applyRefs
is simular to mergeRef
, applyRef
is similar to assignRef
useForkRef
is simular to useMergeRefs
, but accepts only two arguments.merge-refs
is simular to useMergeRefs
, but not a hook and does not provide "stable" reference.Is it a rocket science? No,
RefObject
is no more than{current: ref}
, anduse-callback-ref
is no more thangetter
andsetter
on that field.
MIT
FAQs
The same useRef, but with callback
The npm package use-callback-ref receives a total of 5,646,137 weekly downloads. As such, use-callback-ref popularity was classified as popular.
We found that use-callback-ref demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.