From ece1982b154ea0fc93c1c572f1b12c778897ae31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ella=20van=C2=A0Durpe?= Date: Wed, 16 Dec 2020 21:48:42 +0200 Subject: [PATCH] Clearer documentation --- packages/compose/README.md | 14 +++++++---- .../compose/src/hooks/use-merge-refs/index.js | 24 ++++++++++++------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/packages/compose/README.md b/packages/compose/README.md index 1f356cc71ca39c..0353db4ef66af9 100644 --- a/packages/compose/README.md +++ b/packages/compose/README.md @@ -279,15 +279,21 @@ _Returns_ # **useMergeRefs** Merges refs into one ref callback. Ensures the merged ref callbacks are only -called when it changes or when the ref value changes. If you don't wish a ref -callback to be called on every render, wrap it with `useCallback( ref, [] )`. -Dependencies can be added, but when a dependency changes, the ref callback -will be called with the same node. +called when it changes (as a result of a `useCallback` dependency update) or +when the ref value changes. If you don't wish a ref callback to be called on +every render, wrap it with `useCallback( ref, [] )`. +Dependencies can be added, but when a dependency changes, the old ref +callback will be called with `null` and the new ref callback will be called +with the same node. _Parameters_ - _refs_ `Array<(RefObject|RefCallback)>`: The refs to be merged. +_Returns_ + +- `RefCallback`: The merged ref callback. + # **usePrevious** Use something's value from the previous render. diff --git a/packages/compose/src/hooks/use-merge-refs/index.js b/packages/compose/src/hooks/use-merge-refs/index.js index 716b6767d93f6b..683ff0bebb745e 100644 --- a/packages/compose/src/hooks/use-merge-refs/index.js +++ b/packages/compose/src/hooks/use-merge-refs/index.js @@ -8,12 +8,16 @@ import { useRef, useCallback } from '@wordpress/element'; /** * Merges refs into one ref callback. Ensures the merged ref callbacks are only - * called when it changes or when the ref value changes. If you don't wish a ref - * callback to be called on every render, wrap it with `useCallback( ref, [] )`. - * Dependencies can be added, but when a dependency changes, the ref callback - * will be called with the same node. + * called when it changes (as a result of a `useCallback` dependency update) or + * when the ref value changes. If you don't wish a ref callback to be called on + * every render, wrap it with `useCallback( ref, [] )`. + * Dependencies can be added, but when a dependency changes, the old ref + * callback will be called with `null` and the new ref callback will be called + * with the same node. * * @param {Array} refs The refs to be merged. + * + * @return {RefCallback} The merged ref callback. */ export default function useMergeRefs( refs ) { const lastValue = useRef( null ); @@ -22,12 +26,14 @@ export default function useMergeRefs( refs ) { return useCallback( ( value ) => { refs.forEach( ( ref, index ) => { if ( typeof ref === 'function' ) { - // Only call a ref when it wants to be called: - // - The value changes. - // - The ref callback has changed (e.g. an updated dependency). + // Only call a ref callback if it has changes, e.g. a dependency + // change in `useCallback`, EXCEPT if the value changes, then + // the ref callback must always be called. + // Any other ref callbacks WON'T be called if it doesn't change, + // e.g. if no `useCallback` dependencies change. if ( - value !== lastValue.current || - lastRefs[ index ] !== ref + lastRefs[ index ] !== ref || + value !== lastValue.current ) { ref( value ); }