/* eslint-disable @typescript-eslint/no-unsafe-argument */ /* eslint-disable @typescript-eslint/ban-ts-comment */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import React, { useMemo, useState, useRef, useCallback } from 'react'; import { Obj } from 'src/type'; import { isFunction, getValueByPath } from './util'; export function useSecond(callback: () => void, deps: any[]) { const hasBeSecond = useRef(false); useMemo(() => { if (hasBeSecond.current) { callback instanceof Function && callback(); } else { hasBeSecond.current = true; } }, [...deps]); } export interface unitValueI { defaultValuePropName: any; valuePropName: string; } export function useUnitValue( props: Obj, opts: unitValueI, ): [any, React.Dispatch] { const { defaultValuePropName = [], valuePropName = 'value' } = opts; const [data, setData] = useState( props[valuePropName] ?? defaultValuePropName, ); useSecond(() => { setData(props[valuePropName] as T); }, [props[valuePropName]]); return [data, setData]; } export interface controlValueI extends unitValueI { changePropName: string; [propName: string]: any; } export function useControlValue( props: Obj, opts: controlValueI, ): [any, React.Dispatch] { const { defaultValuePropName = 'defaultValue', valuePropName = 'value', changePropName = 'onChange', defaultValue, } = opts; const [data, setData] = useState( props?.[valuePropName] ?? props?.[defaultValuePropName] ?? defaultValue, ); const setHandler = useCallback( (...args: any[]) => { const finalChange = getValueByPath( props, changePropName.split('.'), null, ); if (isFunction(finalChange)) { // @ts-ignore finalChange(...args); } // @ts-ignore !(valuePropName in (props || {})) && setData(...args); }, [props, valuePropName, changePropName], ); useSecond(() => { setData(props[valuePropName]); }, [props?.[valuePropName]]); // @ts-ignore return [data, setHandler]; } export const useUpdate = () => { const [, setState] = useState({}); return useCallback(() => setState({}), []); };