MCPcopy
hub / github.com/mui/material-ui / useControlled

Function useControlled

packages/mui-utils/src/useControlled/useControlled.ts:25–78  ·  view source on GitHub ↗
(
  props: UseControlledProps<T>,
)

Source from the content-addressed store, hash-verified

23}
24
25export default function useControlled<T = unknown>(
26 props: UseControlledProps<T>,
27): [T, React.Dispatch<React.SetStateAction<T | undefined>>] {
28 const { controlled, default: defaultProp, name, state = 'value' } = props;
29 // isControlled is ignored in the hook dependency lists as it should never change.
30 const { current: isControlled } = React.useRef(controlled !== undefined);
31 const [valueState, setValue] = React.useState<T | undefined>(defaultProp);
32 const value = isControlled ? controlled : valueState;
33
34 if (process.env.NODE_ENV !== 'production') {
35 React.useEffect(() => {
36 if (isControlled !== (controlled !== undefined)) {
37 console.error(
38 [
39 `MUI: A component is changing the ${
40 isControlled ? '' : 'un'
41 }controlled ${state} state of ${name} to be ${isControlled ? 'un' : ''}controlled.`,
42 'Elements should not switch from uncontrolled to controlled (or vice versa).',
43 `Decide between using a controlled or uncontrolled ${name} ` +
44 'element for the lifetime of the component.',
45 "The nature of the state is determined during the first render. It's considered controlled if the value is not `undefined`.",
46 'More info: https://fb.me/react-controlled-components',
47 ].join('\n'),
48 );
49 }
50 }, [state, name, controlled]);
51
52 const { current: defaultValue } = React.useRef(defaultProp);
53
54 React.useEffect(() => {
55 if (!isControlled && JSON.stringify(defaultProp) !== JSON.stringify(defaultValue)) {
56 console.error(
57 [
58 `MUI: A component is changing the default ${state} state of an uncontrolled ${name} after being initialized. ` +
59 `To suppress this warning opt to use a controlled ${name}.`,
60 ].join('\n'),
61 );
62 }
63 }, [JSON.stringify(defaultProp)]);
64 }
65
66 const setValueIfUncontrolled: React.Dispatch<React.SetStateAction<T | undefined>> =
67 React.useCallback((newValue: React.SetStateAction<T | undefined>) => {
68 if (!isControlled) {
69 setValue(newValue);
70 }
71 }, []);
72
73 // TODO: provide overloads for the useControlled function to account for the case where either
74 // controlled or default is not undefined.
75 // In that case the return type should be [T, React.Dispatch<React.SetStateAction<T>>]
76 // otherwise it should be [T | undefined, React.Dispatch<React.SetStateAction<T | undefined>>]
77 return [value as T, setValueIfUncontrolled];
78}

Callers 12

Rating.jsFile · 0.90
TestComponentFunction · 0.85
TestComponentArrayFunction · 0.85
SelectInput.jsFile · 0.85
Tooltip.jsFile · 0.85
useSliderFunction · 0.85
SpeedDial.jsFile · 0.85
useAutocompleteFunction · 0.85
SwitchBase.jsFile · 0.85
RadioGroup.jsFile · 0.85
Accordion.jsFile · 0.85
usePaginationFunction · 0.85

Calls 1

setValueFunction · 0.50

Tested by 2

TestComponentFunction · 0.68
TestComponentArrayFunction · 0.68

Used in the wild real call sites across dependent graphs

searching dependent graphs…