import { useState } from 'react'; type ArrayState = T[]; type ArrayActions = { clear: () => void; down: (itemKey: T[K]) => void; findItem: (elementKey: T[K]) => T | undefined; pop: () => void; push: (...newItems: T[]) => void; remove: (itemKey: T[K]) => void; reset: () => void; reverse: () => void; shift: () => void; sort: (compareFn?: (a: T, b: T) => number) => void; splice: (start: number, deleteCount?: number, ...items: T[]) => void; unshift: (...newItems: T[]) => void; up: (itemKey: T[K]) => void; updateState: (newState: T[] | ((prevState: T[]) => T[])) => void; }; export default function useArray(initState: T[], key?: K): [ArrayState, ArrayActions] { const [state, setState] = useState(initState); const resolvedKey = (key ?? 'id') as K; const updateState = (newState: T[] | ((prevState: T[]) => T[])) => { setState(newState); }; const push = (...newItems: T[]) => { setState(prevState => { // 确保新添加的元素的 key 是唯一的 const newState = [...prevState, ...newItems]; return newState.filter( (item, index, self) => index === self.findIndex(t => t[resolvedKey] === item[resolvedKey]) ); }); }; const unshift = (...newItems: T[]) => { setState(prevState => { // 确保新添加的元素的 key 是唯一的 const newState = [...newItems, ...prevState]; return newState.filter( (item, index, self) => index === self.findIndex(t => t[resolvedKey] === item[resolvedKey]) ); }); }; const remove = (itemKey: T[K]) => { setState(prevState => prevState.filter(i => i[resolvedKey] !== itemKey)); }; // 上移函数 const up = (itemKey: T[K]) => { setState(prevState => { const index = prevState.findIndex(i => i[resolvedKey] === itemKey); // 如果该元素在第一个位置,就不能上移 if (index <= 0) return prevState; // 交换当前元素与上一个元素的位置 const newState = [...prevState]; [newState[index], newState[index - 1]] = [newState[index - 1], newState[index]]; return newState; }); }; // 下移函数 const down = (itemKey: T[K]) => { setState(prevState => { const index = prevState.findIndex(i => i[resolvedKey] === itemKey); // 如果该元素已经在最后一个位置或找不到该元素,就不能下移 if (index === prevState.length - 1 || index === -1) return prevState; // 交换当前元素与下一个元素的位置 const newState = [...prevState]; [newState[index], newState[index + 1]] = [newState[index + 1], newState[index]]; return newState; }); }; const pop = () => { setState(prevState => prevState.slice(0, -1)); }; const shift = () => { setState(prevState => prevState.slice(1)); }; const reverse = () => { setState(prevState => [...prevState].reverse()); }; const sort = (compareFn?: (a: T, b: T) => number) => { setState(prevState => [...prevState].sort(compareFn)); }; const splice = (start: number, deleteCount?: number, ...items: T[]) => { const end = deleteCount ?? 0; setState(prevState => { // 使用 spread 运算符 ... 和 splice() 方法进行修改 const newState = [...prevState]; newState.splice(start, end, ...items); return newState; }); }; const clear = () => { setState([]); }; const reset = () => { setState(initState); }; const findItem = (elementKey: T[K]) => { return state.find(item => item[resolvedKey] === elementKey); }; return [ state, { clear, down, findItem, pop, push, remove, reset, reverse, shift, sort, splice, unshift, up, updateState } ]; }