Skip to content

Commit

Permalink
Switch to new suggested implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ciampo committed Nov 30, 2023
1 parent e1e9d98 commit 749a884
Showing 1 changed file with 16 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* WordPress dependencies
*/
import { usePrevious } from '@wordpress/compose';
import { useEffect, useState } from '@wordpress/element';
import { useEffect, useRef } from '@wordpress/element';

/**
* Internal dependencies
Expand All @@ -21,34 +21,25 @@ type ValueProp = ToggleGroupControlProps[ 'value' ];
export function useComputeControlledOrUncontrolledValue(
valueProp: ValueProp
): { value: ValueProp; defaultValue: ValueProp } {
const [
hasEverBeenUsedInControlledMode,
setHasEverBeenUsedInControlledMode,
] = useState( false );
const previousValueProp = usePrevious( valueProp );
const prevValueProp = usePrevious( valueProp );
const prevIsControlled = useRef( false );

// Assume the component is being used in controlled mode on the first re-render
// that has a different `valueProp` from the previous render.
const isControlled =
prevIsControlled.current ||
( prevValueProp !== undefined &&
valueProp !== undefined &&
prevValueProp !== valueProp );
useEffect( () => {
if ( ! hasEverBeenUsedInControlledMode ) {
// Assume the component is being used in controlled mode if:
// - the `value` prop is not `undefined`
// - the `value` prop was not previously `undefined` and was given a new value
setHasEverBeenUsedInControlledMode(
valueProp !== undefined &&
previousValueProp !== undefined &&
valueProp !== previousValueProp
);
}
}, [ valueProp, previousValueProp, hasEverBeenUsedInControlledMode ] );
prevIsControlled.current = isControlled;
}, [ isControlled ] );

let value, defaultValue;

if ( hasEverBeenUsedInControlledMode ) {
if ( isControlled ) {
// When in controlled mode, use `''` instead of `undefined`
value = valueProp ?? '';
} else {
// When in uncontrolled mode, the `value` should be intended as the initial value
defaultValue = valueProp;
return { value: valueProp ?? '', defaultValue: undefined };
}

return { value, defaultValue };
// When in uncontrolled mode, the `value` should be intended as the initial value
return { value: undefined, defaultValue: valueProp };
}

0 comments on commit 749a884

Please sign in to comment.