Skip to content

Commit 29aa868

Browse files
committed
[WIP] useProxyState hook
1 parent 8dc3260 commit 29aa868

15 files changed

Lines changed: 294 additions & 20 deletions

File tree

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { useCallback, useRef } from "react";
2+
import { useArray } from "../../../../../../packages/react-tools/src";
3+
4+
/**
5+
The component has:
6+
- A _useArray_ internal state.
7+
- An uncontrolled input with _inputRef_ ref used to execute buttons actions.
8+
- A button _Push_ that push the input value into state by _push_ method of Array interface.
9+
- A button _Pop_ that remove last item into state by _pop_ method of Array interface.
10+
*/
11+
const UseArray = () => {
12+
const array = useArray<string>();
13+
14+
const inputRef = useRef<HTMLInputElement>(null);
15+
16+
const pop = useCallback(() => {
17+
array.pop();
18+
}, [array]);
19+
20+
const push = useCallback(() => {
21+
array.push(inputRef.current!.value);
22+
}, [array]);
23+
24+
return (<>
25+
{array.join(",")}
26+
<br />
27+
<input ref={inputRef} type="text" />
28+
<br />
29+
<div style={{ marginTop: 15, gridTemplateColumns: 'auto auto', justifyContent: 'center', display: 'grid', gap: '5px' }}>
30+
<button onClick={push}>Push</button>
31+
<button onClick={pop}>Pop</button>
32+
</div>
33+
</>);
34+
}
35+
36+
UseArray.displayName = "UseArray";
37+
38+
export { UseArray }

apps/react-tools-demo/src/constants/components.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export const COMPONENTS = [
1111
"useSessionStorageState",
1212
"useMap",
1313
"useSet",
14+
"useArray",
1415
"useMemoizedFunction",
1516
"useMemoCompare",
1617
"useMemoDeepCompare",
@@ -29,6 +30,7 @@ export const COMPONENTS = [
2930
"isDeepEqual",
3031
"isTouchEvent",
3132
"isMouseEvent",
32-
"isClient"
33+
"isClient",
34+
"isPlainObject"
3335
]
3436
]
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# useArray
2+
Hooks to use _Array data structure_ to handle component state with all Array methods.
3+
4+
## Usage
5+
6+
```tsx
7+
const UseArray = () => {
8+
const array = useArray<string>();
9+
10+
const inputRef = useRef<HTMLInputElement>(null);
11+
12+
const pop = useCallback(() => {
13+
array.pop();
14+
}, [array]);
15+
16+
const push = useCallback(() => {
17+
array.push(inputRef.current!.value);
18+
}, [array]);
19+
20+
const concat = useCallback(() => {
21+
array.concat(inputRef.current!.value);
22+
}, [array]);
23+
24+
return (<>
25+
{array.join(",")}
26+
<br />
27+
<input ref={inputRef} type="text" />
28+
<br />
29+
<div style={{ marginTop: 15, gridTemplateColumns: 'auto auto', justifyContent: 'center', display: 'grid', gap: '5px' }}>
30+
<button onClick={push}>Push</button>
31+
<button onClick={pop}>Pop</button>
32+
<button onClick={concat}>Concat</button>
33+
</div>
34+
</>);
35+
}
36+
37+
UseArray.displayName = "UseArray";
38+
39+
export { UseArray }
40+
```
41+
42+
> The component has:
43+
> - A _useArray_ internal state.
44+
> - An uncontrolled input with _inputRef_ ref used to execute buttons actions.
45+
> - A button _Push_ that push the input value into state by _push_ method of Array interface.
46+
> - A button _Pop_ that remove last item into state by _pop_ method of Array interface.
47+
> - A button _Concat_ that concats the input value with state by _concat_ method of Array interface.
48+
49+
50+
## API
51+
52+
```tsx
53+
useArray <T>(initialState?: Array<T> | (() => Array<T>))
54+
```
55+
56+
> ### Params
57+
>
58+
> - __initialState?__: _Array<T> | (() => Array<T>_
59+
An Array or function that returns it.
60+
>
61+
62+
> ### Returns
63+
>
64+
>
65+
> - _Array<T>_
66+
>

apps/react-tools-demo/src/markdown/useMap.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export {UseMap}
5959
> - A button _Delete_ that remove item into state by _key_, written in input by _delete_ method of Map interface.
6060
> - A button _Clear_ that clear state by _clear_ method of Map interface.
6161
> - A button _IncrementAll_ that adds 1 to every value into map by _forEach_ method of Map interface.
62+
> - A variable parsed create with useMemo that memoized a concatenated string of state key-value pairs, separated by comma.
6263
6364

6465
## API

apps/react-tools-demo/src/markdown/useSet.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ useSet <T>(initialState?: Iterable<T> | (() => Iterable<T>))
6464
> ### Params
6565
>
6666
> - __initialState?__: _Iterable<T> | (() => Iterable<T>)_
67-
An Array or other iterable object whose elements are key-value pairs, or function that returns it.
67+
An iterable object whose elements are added to Set, or function that returns it.
6868
>
6969
7070
> ### Returns

apps/react-tools-demo/src/router/Router.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ import isDeepEqualMD from '../markdown/isDeepEqual.md?url';
2525
import isMouseEventMD from '../markdown/isMouseEvent.md?url';
2626
import isTouchEventMD from '../markdown/isTouchEvent.md?url';
2727
import isClientMD from '../markdown/isClient.md?url';
28+
import isPlainObjectMD from '../markdown/isPlainObject.md?url';
2829
import usePubSubModelMD from '../markdown/usePubSubModel.md?url';
2930
import useEventDispatcherMD from '../markdown/useEventDispatcher.md?url';
3031
import useLocalStorageStateMD from '../markdown/useLocalStorageState.md?url';
3132
import useSessionStorageStateMD from '../markdown/useSessionStorageState.md?url';
3233
import useMapMD from '../markdown/useMap.md?url';
3334
import useSetMD from '../markdown/useSet.md?url';
35+
import useArrayMD from '../markdown/useArray.md?url';
3436
import { UsePrevious } from '../components/hooks/usePrevious/UsePrevious';
3537
import { UseStateHistory } from '../components/hooks/useStateHistory/UseStateHistory';
3638
import { UseCallbackCompare } from '../components/hooks/useCallbackCompare/UseCallbackCompare';
@@ -48,6 +50,7 @@ import { UseEventListener } from '../components/hooks/useEventListener/UseEventL
4850
import { UseEventDispatcher } from '../components/hooks/useEventDispatcher/UseEventDispatcher';
4951
import { UseMap } from '../components/hooks/useMap/UseMap';
5052
import { UseSet } from '../components/hooks/useSet/UseSet';
53+
import { UseArray } from '../components/hooks/useArray/UseArray';
5154

5255
function Router() {
5356
const router = createBrowserRouter([
@@ -132,6 +135,13 @@ function Router() {
132135
markdown={useSetMD}
133136
/>
134137
},
138+
{
139+
path: "/useArray",
140+
element: <ComponentLayout
141+
component={<UseArray />}
142+
markdown={useArrayMD}
143+
/>
144+
},
135145
{
136146
path: "/useMemoizedFunction",
137147
element: <ComponentLayout
@@ -244,6 +254,11 @@ function Router() {
244254
source={isClientMD}
245255
/>
246256
},
257+
{
258+
path: "/isPlainObject",
259+
element: <MarkdownLayout source={isPlainObjectMD}
260+
/>
261+
}
247262
]
248263
}
249264
]);

packages/react-tools/README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
- [x] useReducerHistoryGetter
1010
- [x] useLocalStorage
1111
- [x] useSessionStorage
12-
- [-] useMap (da sistemare interfaccia jsdoc e ci sono problemi col generatore di markdown)
13-
- [ ] useSet
14-
- [ ] useArray
12+
- [x] useMap
13+
- [x] useSet
14+
- [x] useArray
15+
- [ ] useProxyState
1516
- __EFFECTS__
1617
- [x] useCallbackCompare
1718
- [x] useCallbackDeepCompare
@@ -72,7 +73,8 @@
7273
- [x] isDeepEqual
7374
- [x] isMouseEvent
7475
- [x] isTouchEvent
75-
- [ ] isClient (thinking if it is necessary)
76+
- [x] isClient
77+
- [x] isPlainObject
7678

7779
## ESlint configuration
7880
To validate dependencies of custom hooks like `useMemoCompare`, configure `exhaustive-deps` with the `additionalHooks` option

packages/react-tools/src/hooks/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export { useLocalStorageState } from './useLocalStorageState';
88
export { useSessionStorageState } from './useSessionStorageState';
99
export { useMap } from './useMap';
1010
export { useSet } from './useSet';
11+
export { useArray } from './useArray';
1112
export { useMemoizedFunction } from './useMemoizedFunction';
1213
export { useMemoCompare } from "./useMemoCompare";
1314
export { useMemoDeepCompare } from './useMemoDeepCompare';
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { useState } from "react"
2+
3+
/**
4+
* __`useArray`__: Hooks to use _Array data structure_ to handle component state with all Array methods.
5+
* @param {Array<T> | (() => Array<T>} [initialState] - An Array or function that returns it.
6+
* @returns {Array<T>}
7+
*/
8+
export const useArray = <T>(initialState?: Array<T> | (() => Array<T>)) => {
9+
const [array, setArray] = useState<Array<T>>(() => (initialState instanceof Function ? initialState() : initialState ? initialState : new Array<T>()));
10+
11+
array.copyWithin = (target: number, start: number, end?: number): T[] => {
12+
const arr = [...array].copyWithin(target, start, end);
13+
setArray(arr);
14+
return arr;
15+
}
16+
17+
array.fill = (value: T, start?: number, end?: number): T[] => {
18+
const arr = [...array].fill(value, start, end);
19+
setArray(arr);
20+
return arr;
21+
}
22+
23+
array.pop = (): T|undefined => {
24+
const arr = [...array];
25+
const removedItem = arr.pop();
26+
setArray(arr);
27+
return removedItem;
28+
}
29+
30+
array.push = (...items: T[]): number => {
31+
const arr = [...array];
32+
const result = arr.push(...items);
33+
setArray(arr);
34+
return result;
35+
}
36+
37+
array.reverse = (): T[] => {
38+
const arr = [...array].reverse();
39+
setArray(arr);
40+
return arr;
41+
}
42+
43+
array.shift = (): T | undefined => {
44+
const arr = [...array];
45+
const result = arr.shift();
46+
setArray(arr);
47+
return result;
48+
}
49+
50+
array.sort = (compareFn?: ((a: T, b: T) => number)): T[] => {
51+
const arr = [...array].sort(compareFn);
52+
setArray(arr);
53+
return arr;
54+
}
55+
56+
array.splice = (start: number, deleteCount: number, ...items: T[]): T[] => {
57+
const arr = [...array].splice(start, deleteCount, ...items);
58+
setArray(arr);
59+
return arr;
60+
}
61+
62+
array.unshift = (...items: T[]): number => {
63+
const arr = [...array];
64+
const result = arr.unshift(...items);
65+
setArray(arr);
66+
return result;
67+
}
68+
69+
return array;
70+
}

packages/react-tools/src/hooks/useMap.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@ export const useMap = <K, V>(initialState?: Iterable<readonly [K, V]> | (() => I
99
const [map, setMap] = useState<Map<K, V>>(()=>new Map<K, V>(initialState instanceof Function ? initialState() : initialState));
1010

1111
map.set = (key: K, value: V) => {
12-
setMap(prev => {
13-
const temp = new Map(prev);
14-
temp.set(key, value);
15-
return temp
16-
});
17-
return map;
12+
const temp = new Map(map);
13+
temp.set(key, value);
14+
setMap(temp);
15+
return temp;
1816
}
1917

2018
map.clear = () => {

0 commit comments

Comments
 (0)