@razorpay/blade
Version:
The Design System that powers Razorpay
47 lines (44 loc) • 2.09 kB
JavaScript
import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
import * as React from 'react';
import { useCallbackRef } from './useCallbackRef.js';
/**
* React hook for using controlling component state.
*
* It automatically handles controlled and uncontrolled state,
* while internally giving us the state value so that we can react to the changes.
*
* @example
* In checkbox we want to internally track the checked state to be able to render the correct Icon
* but also want to provide controlled and uncontrolled behavior to user
*/
function useControllableState(props) {
var valueProp = props.value,
defaultValue = props.defaultValue,
onChange = props.onChange,
_props$shouldUpdate = props.shouldUpdate,
shouldUpdate = _props$shouldUpdate === void 0 ? function (prev, next) {
return prev !== next;
} : _props$shouldUpdate;
var onChangeProp = useCallbackRef(onChange);
var shouldUpdateProp = useCallbackRef(shouldUpdate);
var _React$useState = React.useState(defaultValue),
_React$useState2 = _slicedToArray(_React$useState, 2),
valueState = _React$useState2[0],
setValue = _React$useState2[1];
var _React$useRef = React.useRef(valueProp !== undefined),
isControlled = _React$useRef.current;
var value = isControlled && typeof valueProp !== 'undefined' ? valueProp : valueState;
var updateValue = useCallbackRef(function (next) {
var skipUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var extraData = arguments.length > 2 ? arguments[2] : undefined;
var nextValue = next(value);
if (!isControlled) setValue(nextValue);
// We don't want to call onChange if skipUpdate is true or if the value is not changed
if (!shouldUpdateProp(value, nextValue)) return;
if (skipUpdate) return;
onChangeProp === null || onChangeProp === void 0 ? void 0 : onChangeProp(nextValue, extraData);
}, [isControlled, onChangeProp, value, shouldUpdateProp]);
return [value, updateValue];
}
export { useControllableState };
//# sourceMappingURL=useControllable.js.map