Manages state that can be either controlled by a prop or uncontrolled internally, warning on mode switches.
export function useControllableState<T>({
prop,
defaultProp,
onChange = () => {},
caller,
}: UseControllableStateParams<T>): [T, SetStateFn<T>] {
const [uncontrolledProp, setUncontrolledProp, onChangeRef] = useUncontrolledState({
defaultProp,
onChange,
});
const isControlled = prop !== undefined;
const value = isControlled ? prop : uncontrolledProp;
// OK to disable conditionally calling hooks here because they will always run
// consistently in the same environment. Bundlers should be able to remove the
// code block entirely in production.
/* eslint-disable react-hooks/rules-of-hooks */
if (IS_DEVELOPMENT) {
const isControlledRef = React.useRef(prop !== undefined);
React.useEffect(() => {
const wasControlled = isControlledRef.current;
... (truncated -- full source via MCP)
See the full source, get the GitHub permalink, and search 40K more like it.
Get a free API key