Awesome Open Source
Awesome Open Source

πŸ€™ use-callback-ref πŸ“ž

The same `useRef` but it will callback: πŸ“ž Hello! Your ref was changed!
Travis bundle size

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.

– Hooks API Reference

Read more about use-callback pattern and use cases:

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

All 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.

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.

createCallbackRef - to replace React.createRef

  • 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.

callback in both cases is callback(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 = (newValue) => {...}
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); 

useTransformRef (to replace React.useImperativeHandle)

πŸ€” 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, 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.

Similar packages:

  • apply-ref - applyRefs is simular to mergeRef, applyRef is similar to assignRef
  • useForkRef - useForkRef is simular to useMergeRefs, but accepts only two arguments.
  • react-merge-refs - 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}, and use-callback-ref is no more than getter and setter on that field.



Get A Weekly Email With Trending Projects For These Topics
No Spam. Unsubscribe easily at any time.
typescript (9,998)Β 
react (5,057)Β 
hooks (239)Β 
callback (41)Β 

Find Open Source By Browsing 7,000 Topics Across 59 Categories

Advertising πŸ“¦Β 10
All Projects
Application Programming Interfaces πŸ“¦Β 124
Applications πŸ“¦Β 192
Artificial Intelligence πŸ“¦Β 78
Blockchain πŸ“¦Β 73
Build Tools πŸ“¦Β 113
Cloud Computing πŸ“¦Β 80
Code Quality πŸ“¦Β 28
Collaboration πŸ“¦Β 32
Command Line Interface πŸ“¦Β 49
Community πŸ“¦Β 83
Companies πŸ“¦Β 60
Compilers πŸ“¦Β 63
Computer Science πŸ“¦Β 80
Configuration Management πŸ“¦Β 42
Content Management πŸ“¦Β 175
Control Flow πŸ“¦Β 213
Data Formats πŸ“¦Β 78
Data Processing πŸ“¦Β 276
Data Storage πŸ“¦Β 135
Economics πŸ“¦Β 64
Frameworks πŸ“¦Β 215
Games πŸ“¦Β 129
Graphics πŸ“¦Β 110
Hardware πŸ“¦Β 152
Integrated Development Environments πŸ“¦Β 49
Learning Resources πŸ“¦Β 166
Legal πŸ“¦Β 29
Libraries πŸ“¦Β 129
Lists Of Projects πŸ“¦Β 22
Machine Learning πŸ“¦Β 347
Mapping πŸ“¦Β 64
Marketing πŸ“¦Β 15
Mathematics πŸ“¦Β 55
Media πŸ“¦Β 239
Messaging πŸ“¦Β 98
Networking πŸ“¦Β 315
Operating Systems πŸ“¦Β 89
Operations πŸ“¦Β 121
Package Managers πŸ“¦Β 55
Programming Languages πŸ“¦Β 245
Runtime Environments πŸ“¦Β 100
Science πŸ“¦Β 42
Security πŸ“¦Β 396
Social Media πŸ“¦Β 27
Software Architecture πŸ“¦Β 72
Software Development πŸ“¦Β 72
Software Performance πŸ“¦Β 58
Software Quality πŸ“¦Β 133
Text Editors πŸ“¦Β 49
Text Processing πŸ“¦Β 136
User Interface πŸ“¦Β 330
User Interface Components πŸ“¦Β 514
Version Control πŸ“¦Β 30
Virtualization πŸ“¦Β 71
Web Browsers πŸ“¦Β 42
Web Servers πŸ“¦Β 26
Web User Interface πŸ“¦Β 210