All files / useObject index.ts

100% Statements 75/75
100% Branches 14/14
100% Functions 6/6
100% Lines 75/75

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 751x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 12x 12x 12x 12x 12x 12x 12x 1x 1x 12x 12x 5x 4x 4x 4x 4x 12x 12x 1x 1x 1x 1x 1x 1x 12x 12x 3x 2x 2x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x
import { useState } from 'react'
import { equal, ObjectType } from 'abandonjs'
 
type ObjectValue<UseObjectType = ObjectType> = UseObjectType[keyof UseObjectType]
 
export interface UseObjectActions<ObjectValueType = ObjectType> {
	/**
	 * @description 直接替换掉管理的值
	 * @param record {object}
	 */
	setObject: (record: ObjectValueType) => void
	/**
	 * @description 设置值
	 * @param key {string} 属性名
	 * @param value {unknown} 属性值
	 * @param force {boolean=false} false:若和当前值相等则不执行
	 */
	set: (key: keyof ObjectValueType, value: ObjectValue<ObjectValueType>, force?: boolean) => void
	/**
	 * @description 删除属性
	 * @param key {string} 删除的属性
	 */
	remove: (key: keyof ObjectValueType) => void
	/**
	 * @description 重置
	 * @param force {boolean=false} false:若和当前值相等则不执行
	 */
	reset: (force?: boolean) => void
}
 
/**
 * @title useObject<Object>
 * @description 管理对象状态
 * @param initialValue {?Object}
 * @returns [object, Actions<Object>]
 */
export function useObject<ObjectValueType = ObjectType>(initialValue?: ObjectValueType): readonly [ObjectValueType, UseObjectActions<ObjectValueType>] {
 
	const getInitialValue = () => initialValue || {} as ObjectValueType
 
	const [state, setState] = useState<ObjectValueType>(() => getInitialValue())
 
	const setObject = (record: ObjectValueType) => {
		if (!equal(record, state)) setState(record)
	}
 
	const set = (key: keyof ObjectValueType, value: ObjectValue<ObjectValueType>, force = false) => {
		if (!force && equal(value, state[key])) return;
		const tempState = { ...state }
		tempState[key] = value
		setState(tempState)
	}
 
	const remove = (key: keyof ObjectValueType) => {
		if (Object.keys(state as ObjectType).includes(key as string)) {
			const tempState = { ...state }
			delete tempState[key]
			setState(tempState)
		}
	}
 
	const reset = (force = false) => {
		if (!force && equal(state, getInitialValue())) return;
		setState(getInitialValue())
	}
 
	return [state,
		{
			set,
			remove,
			reset,
			setObject
		}
	] as const
}