Skip to content

Instantly share code, notes, and snippets.

@nanxiaobei
Created July 14, 2022 08:55
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save nanxiaobei/d4278250d8198282ba61515a5783ea17 to your computer and use it in GitHub Desktop.
同时处理受控和非受控组件
import { SetStateAction, useCallback, useReducer, useRef } from 'react';
// useControlValue
// 同时处理受控和非受控组件
// based on https://github.com/alibaba/hooks/blob/master/packages/hooks/src/useControllableValue/index.ts
function useControlValue<V = any>(props: Record<string, any> = {}) {
const isControlled = 'value' in props;
// value
const value = useRef<V>();
const hasValueInit = useRef(false);
if (isControlled && value.current !== props.value) {
value.current = props.value;
} else if (!hasValueInit.current) {
value.current = props.defaultValue;
}
hasValueInit.current = true;
// setValue
const [, uncontrolledUpdate] = useReducer((s) => !s, false);
const onChangeRef = useRef(props.onChange);
onChangeRef.current = props.onChange;
const setValue = useCallback(
(v: SetStateAction<V>) => {
value.current = v instanceof Function ? v(value.current as V) : v;
onChangeRef.current?.(value.current);
if (!isControlled) uncontrolledUpdate();
},
[isControlled]
);
return [value.current, setValue] as const;
}
export default useControlValue;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment