Outlook_Addin_LLM/node_modules/@fluentui/react-positioning/lib/utils/useCallbackRef.js

50 lines
1.8 KiB
JavaScript

import * as React from 'react';
import { useIsomorphicLayoutEffect } from '@fluentui/react-utilities';
/**
* Creates a MutableRef with ref change callback. Is useful as React.useRef() doesn't notify you when its content
* changes and mutating the .current property doesn't cause a re-render. An opt-out will be use a callback ref via
* React.useState(), but it will cause re-renders always.
*
* https://reactjs.org/docs/hooks-reference.html#useref
* https://github.com/theKashey/use-callback-ref#usecallbackref---to-replace-reactuseref
*
* @param initialValue - initial ref value
* @param callback - a callback to run when value changes
* @param skipInitialResolve - a flag to skip an initial ref report
*
* @example
* const ref = useCallbackRef(0, (newValue, oldValue) => console.log(oldValue, '->', newValue);
* ref.current = 1;
* // prints 0 -> 1
*/ export function useCallbackRef(initialValue, callback, skipInitialResolve) {
const isFirst = React.useRef(true);
const [ref] = React.useState(()=>({
// value
value: initialValue,
// last callback
callback,
// "memoized" public interface
facade: {
get current () {
return ref.value;
},
set current (value){
const last = ref.value;
if (last !== value) {
ref.value = value;
if (skipInitialResolve && isFirst.current) {
return;
}
ref.callback(value, last);
}
}
}
}));
useIsomorphicLayoutEffect(()=>{
isFirst.current = false;
}, []);
// update callback
ref.callback = callback;
return ref.facade;
}