| 63 | } |
| 64 | |
| 65 | function useList<T>(initialList: IHookStateInitAction<T[]> = []): [T[], ListActions<T>] { |
| 66 | const list = useRef(resolveHookState(initialList)); |
| 67 | const update = useUpdate(); |
| 68 | |
| 69 | const actions = useMemo<ListActions<T>>(() => { |
| 70 | const a = { |
| 71 | set: (newList: IHookStateSetAction<T[]>) => { |
| 72 | list.current = resolveHookState(newList, list.current); |
| 73 | update(); |
| 74 | }, |
| 75 | |
| 76 | push: (...items: T[]) => { |
| 77 | items.length && actions.set((curr: T[]) => curr.concat(items)); |
| 78 | }, |
| 79 | |
| 80 | updateAt: (index: number, item: T) => { |
| 81 | actions.set((curr: T[]) => { |
| 82 | const arr = curr.slice(); |
| 83 | |
| 84 | arr[index] = item; |
| 85 | |
| 86 | return arr; |
| 87 | }); |
| 88 | }, |
| 89 | |
| 90 | insertAt: (index: number, item: T) => { |
| 91 | actions.set((curr: T[]) => { |
| 92 | const arr = curr.slice(); |
| 93 | |
| 94 | index > arr.length ? (arr[index] = item) : arr.splice(index, 0, item); |
| 95 | |
| 96 | return arr; |
| 97 | }); |
| 98 | }, |
| 99 | |
| 100 | update: (predicate: (a: T, b: T) => boolean, newItem: T) => { |
| 101 | actions.set((curr: T[]) => curr.map((item) => (predicate(item, newItem) ? newItem : item))); |
| 102 | }, |
| 103 | |
| 104 | updateFirst: (predicate: (a: T, b: T) => boolean, newItem: T) => { |
| 105 | const index = list.current.findIndex((item) => predicate(item, newItem)); |
| 106 | |
| 107 | index >= 0 && actions.updateAt(index, newItem); |
| 108 | }, |
| 109 | |
| 110 | upsert: (predicate: (a: T, b: T) => boolean, newItem: T) => { |
| 111 | const index = list.current.findIndex((item) => predicate(item, newItem)); |
| 112 | |
| 113 | index >= 0 ? actions.updateAt(index, newItem) : actions.push(newItem); |
| 114 | }, |
| 115 | |
| 116 | sort: (compareFn?: (a: T, b: T) => number) => { |
| 117 | actions.set((curr: T[]) => curr.slice().sort(compareFn)); |
| 118 | }, |
| 119 | |
| 120 | filter: <S extends T>( |
| 121 | callbackFn: (value: T, index: number, array: T[]) => value is S, |
| 122 | thisArg?: any |