diff --git a/src/components/UseImmutableTest.tsx b/src/components/UseImmutableTest.tsx
index 9cf3425..6482d3f 100644
--- a/src/components/UseImmutableTest.tsx
+++ b/src/components/UseImmutableTest.tsx
@@ -2,17 +2,18 @@ import useImmutable from './useImmutable';
export default function UseImmutableTest() {
const [imm] = useImmutable({
- x: 0,
- y: 0,
- z: { a: 1, b: 2, c: [0, 1, 2] },
+ index: 0,
+ array: [{ count: 0 }, { count: 1 }, { count: 2 }],
});
return (
{JSON.stringify(imm)}
-
-
+
+
+
+
);
}
diff --git a/src/components/useImmutable.ts b/src/components/useImmutable.ts
index a076c3d..ef2eb6f 100644
--- a/src/components/useImmutable.ts
+++ b/src/components/useImmutable.ts
@@ -66,27 +66,41 @@ function createEdgeForArray(
value: PlainJSArray,
setValue: Dispatch>>
) {
+ const edges = {} as Record;
+
+ const set = (property: number, next: SetStateAction) => {
+ const current = value[property];
+ const nextValue = typeof next === 'function' ? next(current) : next;
+ setValue((value) => [
+ ...value.slice(0, property),
+ nextValue,
+ ...value.slice(property + 1),
+ ]);
+ };
+
return new Proxy(value, {
set: (target, property, value) => {
if (typeof property === 'number') {
- const set = (next: SetStateAction) => {
- const v = typeof next === 'function' ? next(value) : next;
- const edge = createEdge(v, set);
- setValue((v) => [
- ...v.slice(0, property),
- edge,
- ...v.slice(property + 1),
- ]);
- };
-
- set(value);
+ set(property, value);
}
return true;
},
// @ts-expect-error
get: (target, property: keyof PlainJSArray[]) => {
- if (typeof property === 'number') {
- return target[property];
+ if (
+ typeof property === 'number' ||
+ (typeof property === 'string' && /\d+/.test(property))
+ ) {
+ property = +property;
+ if (property in edges) {
+ return edges[property];
+ }
+
+ const item = target[property];
+ const setThis = set.bind(null, property);
+ const edge = createEdge(item, setThis);
+ edges[property] = edge;
+ return edge;
} else {
// @ts-ignore
if (inPlaceArrayOperations.includes(property)) {
@@ -133,7 +147,5 @@ export default function useImmutable(
const edge = useMemo(() => createEdge(value, setValue), [value]);
- console.log('rerendered useImmutable');
-
return [edge, setValue];
}