@navikt/ds-react
Version:
React components from the Norwegian Labour and Welfare Administration.
41 lines (33 loc) • 1.22 kB
text/typescript
// https://github.com/chakra-ui/chakra-ui/tree/5ec0be610b5a69afba01a9c22365155c1b519136/packages/hooks/use-controllable-state
import { useState } from "react";
import { useCallbackRef } from "./useCallbackRef";
export interface UseControllableStateProps<T> {
value?: T;
defaultValue: T | (() => T);
onChange?: (value: T) => void;
}
/**
* `useControllableState` returns the state and function that updates the state, just like React.useState does.
*/
export function useControllableState<T>({
value: valueProp,
defaultValue,
onChange,
}: UseControllableStateProps<T>) {
const onChangeProp = useCallbackRef(onChange);
const [uncontrolledState, setUncontrolledState] = useState(defaultValue);
const controlled = valueProp !== undefined;
const value = controlled ? valueProp : uncontrolledState;
const setValue = useCallbackRef(
(next: React.SetStateAction<T>) => {
const setter = next as (prevState?: T) => T;
const nextValue = typeof next === "function" ? setter(value) : next;
if (!controlled) {
setUncontrolledState(nextValue);
}
onChangeProp(nextValue);
},
[controlled, onChangeProp, value],
);
return [value, setValue] as const;
}