packages/bui-utils/src/hooks/useValue.ts (41 lines of code) (raw):
import { ChangeEvent, useCallback, useRef, useState, useEffect } from 'react';
type Options<T> = {
value?: T;
defaultValue: T;
onChange?: (e: ChangeEvent<HTMLElement>, data: Record<string, any>) => void;
config?: {
name?: string;
state?: string;
};
};
export default function useValue<T>(options: Options<T>) {
const { value, defaultValue, onChange, config = {} } = options;
const { state, name } = config;
const [internalValue, setInternalValue] = useState(defaultValue);
const initialDefaultValue = useRef(defaultValue);
const isControlled = value !== undefined;
// 异常情况
useEffect(() => {
if (
!isControlled &&
JSON.stringify(defaultValue) !==
JSON.stringify(initialDefaultValue.current) &&
state &&
name
) {
console.error(
[
`BUI: A component is changing the default ${state} state of an uncontrolled ${name} after being initialized. ` +
`To suppress this warning opt to use a controlled ${name}.`,
].join('\n'),
);
}
}, [defaultValue]);
const triggerChange = useCallback(
(e, val) => {
setInternalValue(val);
onChange?.(e, { value: val });
},
[onChange],
);
return [isControlled ? value : internalValue, triggerChange] as const;
}