interface: improve memoization of hooks, state

This commit is contained in:
Liam Fitzgerald 2021-06-15 10:53:24 +10:00
parent b54273a999
commit 02632950be
No known key found for this signature in database
GPG Key ID: D390E12C61D1CFFB
6 changed files with 38 additions and 24 deletions

View File

@ -1,4 +1,4 @@
import { DragEvent, useCallback, useEffect, useState } from 'react';
import { DragEvent, useCallback, useEffect, useState, useMemo } from 'react';
function validateDragEvent(e: DragEvent): FileList | File[] | true | null {
const files: File[] = [];
@ -43,7 +43,7 @@ export function useFileDrag(dragged: (f: FileList | File[], e: DragEvent) => voi
}
setDragging(true);
},
[setDragging]
[]
);
const onDrop = useCallback(
@ -56,7 +56,7 @@ export function useFileDrag(dragged: (f: FileList | File[], e: DragEvent) => voi
e.preventDefault();
dragged(files, e);
},
[setDragging, dragged]
[dragged]
);
const onDragOver = useCallback(
@ -77,7 +77,7 @@ export function useFileDrag(dragged: (f: FileList | File[], e: DragEvent) => voi
setDragging(false);
}
},
[setDragging]
[]
);
useEffect(() => {
@ -92,12 +92,12 @@ export function useFileDrag(dragged: (f: FileList | File[], e: DragEvent) => voi
};
}, []);
const bind = {
const bind = useMemo(() => ({
onDragLeave,
onDragOver,
onDrop,
onDragEnter
};
}), [onDragEnter, onDragOver, onDrop, onDragEnter]);
return { bind, dragging };
return useMemo(() => ({ bind, dragging }), [bind, dragging]);
}

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect, useState } from 'react';
import { useMemo, useEffect, useState } from 'react';
function retrieve<T>(key: string, initial: T): T {
const s = localStorage.getItem(key);
@ -12,26 +12,16 @@ function retrieve<T>(key: string, initial: T): T {
return initial;
}
interface SetStateFunc<T> {
(t: T): T;
}
// See microsoft/typescript#37663 for filed bug
type SetState<T> = T extends any ? SetStateFunc<T> : never;
export function useLocalStorageState<T>(key: string, initial: T): any {
const [state, _setState] = useState(() => retrieve(key, initial));
const [state, setState] = useState(() => retrieve(key, initial));
useEffect(() => {
_setState(retrieve(key, initial));
setState(retrieve(key, initial));
}, [key]);
const setState = useCallback(
(s: SetState<T>) => {
const updated = typeof s === 'function' ? s(state) : s;
_setState(updated);
localStorage.setItem(key, JSON.stringify(updated));
},
[_setState, key, state]
);
useEffect(() => {
localStorage.setItem(key, JSON.stringify(state));
}, [state]);
return [state, setState] as const;
return useMemo(() => [state, setState] as const, [state, setState]);
}

View File

@ -1,5 +1,6 @@
import BigIntOrderedMap from '@urbit/api/lib/BigIntOrderedMap';
import { patp2dec } from 'urbit-ob';
import shallow from 'zustand/shallow';
import { Association, deSig, GraphNode, Graphs, FlatGraphs, resourceFromPath, ThreadGraphs, getGraph, getShallowChildren } from '@urbit/api';
import { useCallback } from 'react';
@ -275,7 +276,11 @@ export function useGraphTimesentMap(ship: string, name: string) {
useCallback(s => s.graphTimesentMap[`${deSig(ship)}/${name}`], [ship, name])
);
}
const emptyObject = {};
export function useGraphTimesent(key: string) {
return useGraphState(useCallback(s => s.graphTimesentMap[key] || emptyObject, [key]), shallow);
}
export function useGraphForAssoc(association: Association) {
const { resource } = association;
const { ship, name } = resourceFromPath(resource);

View File

@ -0,0 +1,8 @@
import { useOsDark } from './local';
import { useTheme } from './settings';
export function useDark() {
const osDark = useOsDark();
const theme = useTheme();
return theme === 'dark' || (osDark && theme === 'auto');
}

View File

@ -130,4 +130,9 @@ function withLocalState<P, S extends keyof LocalState, C extends React.Component
});
}
const selOsDark = (s: LocalState) => s.dark;
export function useOsDark() {
return useLocalState(selOsDark);
}
export { useLocalState as default, withLocalState };

View File

@ -124,4 +124,10 @@ export function useShortcut<T extends keyof ShortcutMapping>(
return usePlainShortcut(key, cb);
}
const selTheme = (s: SettingsState) => s.display.theme;
export function useTheme() {
return useSettingsState(selTheme);
}
export default useSettingsState;