Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Commit

Permalink
[fix] get keys from ref of state in usearray (#52)
Browse files Browse the repository at this point in the history
  • Loading branch information
AsPulse authored Apr 4, 2023
1 parent c182345 commit 34af674
Showing 1 changed file with 26 additions and 12 deletions.
38 changes: 26 additions & 12 deletions src/component/sugar/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export function useArray<T>(
): SugarArrayNode<T> {
const newId = useCountingId();
const mountedRef = useRef(false);
const keysRef = useRef<string[]>([]);

const managedSugars = useRef<Array<{ id: string, sugar: Sugar<T> }>>([]);
let defaultKeys: string[] = [];
Expand All @@ -22,7 +23,7 @@ export function useArray<T>(
const newSugar = createEmptySugar(sugar.path, template);
managedSugars.current.push({ id, sugar: newSugar });
newSugar.upstream.listen('updateDirty', ({ isDirty }) => {
if (!keys.includes(id)) return;
if (!keysRef.current.includes(id)) return;
dirtyControl({ isDirty });
});
return newSugar;
Expand All @@ -34,15 +35,16 @@ export function useArray<T>(
sugar.asMounted(sugar => {
notDirtyCheck:
if (!isDirty) {
if (keys.length !== sugar.template.length) break notDirtyCheck;
if (keys.some(i => {
if (keysRef.current.length !== sugar.template.length) break notDirtyCheck;
if (keysRef.current.some(i => {
const managed = getManagedSugar(i);
return managed.mounted && managed.isDirty;
})) return;
}
setDirty(sugar, isDirty);
});
};

if (!mountedRef.current && sugar.mounted) {
debug('WARN', `Sugar is already mounted, but items are not initialized. Remounting... Path: ${sugar.path}`);
mountedRef.current = false;
Expand All @@ -65,6 +67,7 @@ export function useArray<T>(
}

const [ keys, setKeys ] = useState<string[]>(defaultKeys);
keysRef.current = keys;

const mountedSugar = sugar as Sugar<T[]> & { mounted: true };
mountedSugar.get = (): SugarValue<T[]> => {
Expand All @@ -86,25 +89,36 @@ export function useArray<T>(
const keys = value.map((v, i) => {
const id = newId();
const managed = getManagedSugar(id, sugar.template[i] ?? options.template);
managed.upstream.listenOnce('mounted', () => {
( managed as Sugar<T> & { mounted: true } ).set(v);
managed.asMounted(s => {
setTimeout(() => s.set(v));
});
return id;
});
setKeys(keys);
};
mountedSugar.setTemplate = (template: T[], mode: SetTemplateMode = 'merge'): void => {
sugar.template = template;
keys.forEach((id, i) => {
const managed = getManagedSugar(id);
if (!managed.mounted) {
debug('WARN', `Sugar is not mounted when tried to set. Path: ${managed.path}`);
return;
}
managed.setTemplate(template[i] ?? options.template, mode);
const keys = template.map(v => {
const id = newId();
getManagedSugar(id, options.template).asMounted(s => s.setTemplate(v, mode));
return id;
});
setKeys(keys);
};

// refresh dirty for new items or removed items
setDirty(
sugar,
((): boolean => {
if (keysRef.current.length !== sugar.template.length) return true;
if (keysRef.current.some(i => {
const managed = getManagedSugar(i);
return managed.mounted && managed.isDirty;
})) return true;
return false;
})(),
);

return {
useNewId: () => newId(),
useKeys: () => [ keys, (keys: string[]):void => setKeys(keys) ],
Expand Down

0 comments on commit 34af674

Please sign in to comment.