-
-
Notifications
You must be signed in to change notification settings - Fork 219
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
useArraystate and useSetState (#1223)
* feat(usearraystate): added a new hook to manage the contents of an array * feat(usesetstate): manage state of a set in React hook * chore(build): remove unnecessary import * Update packages/rooks/src/hooks/useArrayState.ts Co-authored-by: Qiushi Pan <[email protected]> * chore(pr): address review * feat(changeset): add Co-authored-by: Qiushi Pan <[email protected]>
- Loading branch information
1 parent
4185e59
commit 182e849
Showing
10 changed files
with
404 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"rooks": minor | ||
--- | ||
|
||
add useArrayState and useSetState hooks to manage arrays and sets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#!/usr/bin/env sh | ||
if [ -z "$husky_skip_init" ]; then | ||
debug () { | ||
if [ "$HUSKY_DEBUG" = "1" ]; then | ||
echo "husky (debug) - $1" | ||
fi | ||
} | ||
|
||
readonly hook_name="$(basename -- "$0")" | ||
debug "starting $hook_name..." | ||
|
||
if [ "$HUSKY" = "0" ]; then | ||
debug "HUSKY env variable is set to 0, skipping hook" | ||
exit 0 | ||
fi | ||
|
||
if [ -f ~/.huskyrc ]; then | ||
debug "sourcing ~/.huskyrc" | ||
. ~/.huskyrc | ||
fi | ||
|
||
readonly husky_skip_init=1 | ||
export husky_skip_init | ||
sh -e "$0" "$@" | ||
exitCode="$?" | ||
|
||
if [ $exitCode != 0 ]; then | ||
echo "husky - $hook_name hook exited with code $exitCode (error)" | ||
fi | ||
|
||
if [ $exitCode = 127 ]; then | ||
echo "husky - command not found in PATH=$PATH" | ||
fi | ||
|
||
exit $exitCode | ||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
--- | ||
id: useArrayState | ||
title: useArrayState | ||
sidebar_label: useArrayState | ||
--- | ||
|
||
## About | ||
|
||
Array state manager hook for React. It exposes push, pop, unshift, shift, concat, fill and reverse methods to be able to easily modify the state of an array. | ||
|
||
## Examples | ||
|
||
```jsx | ||
import { useArrayState } from "rooks"; | ||
export default function App() { | ||
const [array, controls] = useArrayState([1, 2, 3]); | ||
return null; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
--- | ||
id: useSetState | ||
title: useSetState | ||
sidebar_label: useSetState | ||
--- | ||
|
||
## About | ||
|
||
Manage the state of a Set in React. Exposes add, delete and clear methods along with the current set to easily manipulate values in a set. | ||
|
||
## Examples | ||
|
||
```jsx | ||
import { useSetState } from "rooks"; | ||
export default function App() { | ||
useSetState(); | ||
return null; | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import { act } from "@testing-library/react"; | ||
import { renderHook } from "@testing-library/react-hooks"; | ||
import { useArrayState } from "../hooks/useArrayState"; | ||
|
||
describe("useArrayState", () => { | ||
it("should be defined", () => { | ||
expect.hasAssertions(); | ||
expect(useArrayState).toBeDefined(); | ||
}); | ||
|
||
it("should initialize correctly", () => { | ||
expect.hasAssertions(); | ||
const { result } = renderHook(() => useArrayState([1, 2, 3])); | ||
|
||
expect(result.current[0]).toEqual([1, 2, 3]); | ||
}); | ||
|
||
it("should push correctly", () => { | ||
expect.hasAssertions(); | ||
const { result } = renderHook(() => useArrayState([1, 2, 3])); | ||
|
||
act(() => { | ||
result.current[1].push(4); | ||
}); | ||
|
||
expect(result.current[0]).toEqual([1, 2, 3, 4]); | ||
}); | ||
|
||
it("should pop correctly", () => { | ||
expect.hasAssertions(); | ||
const { result } = renderHook(() => useArrayState([1, 2, 3])); | ||
|
||
act(() => { | ||
result.current[1].pop(); | ||
}); | ||
|
||
expect(result.current[0]).toEqual([1, 2]); | ||
}); | ||
|
||
it("should unshift correctly", () => { | ||
expect.hasAssertions(); | ||
const { result } = renderHook(() => useArrayState([1, 2, 3])); | ||
|
||
act(() => { | ||
result.current[1].unshift(0); | ||
}); | ||
expect(result.current[0]).toEqual([0, 1, 2, 3]); | ||
}); | ||
|
||
it("should shift correctly", () => { | ||
expect.hasAssertions(); | ||
const { result } = renderHook(() => useArrayState([1, 2, 3])); | ||
|
||
act(() => { | ||
result.current[1].shift(); | ||
}); | ||
expect(result.current[0]).toEqual([2, 3]); | ||
}); | ||
|
||
it("should reverse correctly", () => { | ||
expect.hasAssertions(); | ||
const { result } = renderHook(() => useArrayState([1, 2, 3])); | ||
|
||
act(() => { | ||
result.current[1].reverse(); | ||
}); | ||
|
||
expect(result.current[0]).toEqual([3, 2, 1]); | ||
}); | ||
|
||
it("should concat correctly", () => { | ||
expect.hasAssertions(); | ||
const { result } = renderHook(() => useArrayState([1, 2, 3])); | ||
|
||
act(() => { | ||
result.current[1].concat([4, 5, 6]); | ||
}); | ||
|
||
expect(result.current[0]).toEqual([1, 2, 3, 4, 5, 6]); | ||
}); | ||
|
||
it("should fill correctly", () => { | ||
expect.hasAssertions(); | ||
const { result } = renderHook(() => useArrayState([1, 2, 3])); | ||
|
||
act(() => { | ||
result.current[1].fill(0); | ||
}); | ||
|
||
expect(result.current[0]).toEqual([0, 0, 0]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { renderHook, act } from "@testing-library/react"; | ||
import { useSetState } from "../hooks/useSetState"; | ||
|
||
describe("useSetState", () => { | ||
it("should be defined", () => { | ||
expect.hasAssertions(); | ||
expect(useSetState).toBeDefined(); | ||
}); | ||
|
||
it("should initialize the state with the initialSetValue", () => { | ||
expect.hasAssertions(); | ||
const { result } = renderHook(() => useSetState(new Set([1, 2, 3]))); | ||
|
||
expect(result.current[0]).toEqual(new Set([1, 2, 3])); | ||
}); | ||
|
||
it("should add values to the set", () => { | ||
expect.hasAssertions(); | ||
const { result } = renderHook(() => useSetState(new Set([1, 2, 3]))); | ||
|
||
act(() => { | ||
result.current[1].add(4); | ||
}); | ||
expect(result.current[0]).toEqual(new Set([1, 2, 3, 4])); | ||
}); | ||
|
||
it("should delete values from the set", () => { | ||
expect.hasAssertions(); | ||
const { result } = renderHook(() => useSetState(new Set([1, 2, 3]))); | ||
|
||
act(() => { | ||
result.current[1].delete(2); | ||
}); | ||
|
||
expect(result.current[0]).toEqual(new Set([1, 3])); | ||
}); | ||
|
||
it("should clear the set", () => { | ||
expect.hasAssertions(); | ||
const { result } = renderHook(() => useSetState(new Set([1, 2, 3]))); | ||
|
||
act(() => { | ||
result.current[1].clear(); | ||
}); | ||
expect(result.current[0]).toEqual(new Set()); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { useCallback, useMemo, useState } from "react"; | ||
|
||
type Push<T> = (...args: Parameters<Array<T>["push"]>) => void; | ||
type Pop = () => void; | ||
type Unshift<T> = (...args: Parameters<Array<T>["unshift"]>) => void; | ||
type Shift = () => void; | ||
type Reverse = () => void; | ||
type Concat<T> = (value: T[]) => void; | ||
type Fill<T> = (value: T, start?: number, end?: number) => void; | ||
type Clear = () => void; | ||
|
||
export type UseArrayStateControls<T> = { | ||
push: Push<T>; | ||
pop: Pop; | ||
clear: Clear; | ||
unshift: Unshift<T>; | ||
shift: Shift; | ||
reverse: Reverse; | ||
concat: Concat<T>; | ||
fill: Fill<T>; | ||
}; | ||
|
||
export type UseArrayStateReturnValue<T> = [T[], UseArrayStateControls<T>]; | ||
|
||
/** | ||
* useArrayState | ||
* @description Array state manager hook for React | ||
* @param {Array<T>} initialState Initial state of the array | ||
* @returns {UseArrayStateReturnValue<T>} Array state manager hook for React | ||
* @see {@link https://react-hooks.org/docs/useArrayState} | ||
* | ||
* @example | ||
* | ||
* const [array, controls] = useArrayState([1, 2, 3]); | ||
* | ||
* controls.push(4); // [1, 2, 3, 4] | ||
* controls.pop(); // [1, 2, 3] | ||
* controls.unshift(0); // [0, 1, 2, 3] | ||
* controls.shift(); // [1, 2, 3] | ||
* controls.reverse(); // [3, 2, 1] | ||
* controls.concat([4, 5, 6]); // [3, 2, 1, 4, 5, 6] | ||
* controls.fill(0); // [0, 0, 0, 0, 0, 0] | ||
*/ | ||
function useArrayState<T>(initialArray: T[] = []): UseArrayStateReturnValue<T> { | ||
const [array, setArray] = useState(initialArray); | ||
|
||
const push = useCallback<Push<T>>( | ||
(value) => { | ||
setArray([...array, value]); | ||
}, | ||
[array] | ||
); | ||
|
||
const pop = useCallback<Pop>(() => { | ||
setArray(array.slice(0, array.length - 1)); | ||
}, [array]); | ||
|
||
const clear = useCallback<Clear>(() => { | ||
setArray([]); | ||
}, []); | ||
|
||
const unshift = useCallback<Unshift<T>>( | ||
(value) => { | ||
setArray([value, ...array]); | ||
}, | ||
[array] | ||
); | ||
|
||
const shift = useCallback<Shift>(() => { | ||
setArray(array.slice(1)); | ||
}, [array]); | ||
|
||
const reverse = useCallback<Reverse>(() => { | ||
setArray([...array].reverse()); | ||
}, [array]); | ||
|
||
const concat = useCallback<Concat<T>>( | ||
(value: T[]) => { | ||
setArray([...array, ...value]); | ||
}, | ||
[array] | ||
); | ||
|
||
const fill = useCallback<Fill<T>>( | ||
(value: T, start?: number, end?: number) => { | ||
setArray([...array].fill(value, start, end)); | ||
}, | ||
[array] | ||
); | ||
|
||
const controls = useMemo<UseArrayStateControls<T>>(() => { | ||
return { | ||
push, | ||
pop, | ||
clear, | ||
unshift, | ||
shift, | ||
reverse, | ||
concat, | ||
fill, | ||
}; | ||
}, [push, pop, clear, unshift, shift, reverse, concat, fill]); | ||
|
||
const returnValue = useMemo<UseArrayStateReturnValue<T>>(() => { | ||
return [array, controls]; | ||
}, [array, controls]); | ||
|
||
return returnValue; | ||
} | ||
|
||
export { useArrayState }; |
Oops, something went wrong.
182e849
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
rooks – ./
rooks.vercel.app
rooks-git-main-imbhargav5.vercel.app
react-hooks.org
rooks.arni-creative.com
rooks-imbhargav5.vercel.app