useList
React hook that returns a list and a set of functions to manipulate it
Example
import useList from "@/hooks/useList";
export default function UseListExample() {
const [list, { push, removeAt, insertAt, updateAt, clear }] = useList([
1, 2, 3,
]);
return (
<div className="text-ctp-text">
<div className="flex gap-4">
<button
className="rounded bg-ctp-blue px-4 py-2 text-ctp-base"
onClick={() => push(4)}
>
Push 4
</button>
<button
className="rounded bg-ctp-blue px-4 py-2 text-ctp-base"
onClick={() => removeAt(1)}
>
Remove at 1
</button>
<button
className="rounded bg-ctp-blue px-4 py-2 text-ctp-base"
onClick={() => insertAt( 1,4)}
>
Insert at 1 4
</button>
<button
className="rounded bg-ctp-blue px-4 py-2 text-ctp-base"
onClick={() => updateAt(1,4)}
>
Update at 1 to 4
</button>
<button
className="rounded bg-ctp-blue px-4 py-2 text-ctp-base"
onClick={() => clear()}
>
Clear
</button>
</div>
<div>
{list.map((item, index) => (
<div key={index}>{item}</div>
))}
</div>
</div>
);
}
Code
import { useState, useCallback } from "react";
type UseListReturn<T> = [
T[],
{
set: (newList: T[]) => void;
push: (element: T) => void;
removeAt: (index: number) => void;
insertAt: (index: number, element: T) => void;
updateAt: (index: number, element: T) => void;
clear: () => void;
},
];
/**
* React hook that returns a list and a set of functions to manipulate it
* @param {T[]} defaultList - default list
* @returns {UseListReturn<T>} list and set of functions to manipulate it
*/
export default function useList<T>(defaultList: T[] = []): UseListReturn<T> {
const [list, setList] = useState<T[]>(defaultList);
const set = useCallback((newList: T[]) => {
setList(newList);
}, []);
const push = useCallback((element: T) => {
setList((currentList) => [...currentList, element]);
}, []);
const removeAt = useCallback((index: number) => {
setList((currentList) => [
...currentList.slice(0, index),
...currentList.slice(index + 1),
]);
}, []);
const insertAt = useCallback((index: number, element: T) => {
setList((currentList) => [
...currentList.slice(0, index),
element,
...currentList.slice(index),
]);
}, []);
const updateAt = useCallback((index: number, element: T) => {
setList((currentList) =>
currentList.map((item, i) => (i === index ? element : item)),
);
}, []);
const clear = useCallback(() => setList([]), []);
return [list, { set, push, removeAt, insertAt, updateAt, clear }];
}