feat(ui): use nanostores for useMouseOverNode

This greatly reduces the weight of the event handlers.
This commit is contained in:
psychedelicious
2023-12-31 18:34:47 +11:00
committed by Kent Keirsey
parent b490c8ae27
commit 5168415999
5 changed files with 48 additions and 87 deletions

View File

@ -1,31 +0,0 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { mouseOverFieldChanged } from 'features/nodes/store/nodesSlice';
import { useCallback, useMemo } from 'react';
export const useIsMouseOverField = (nodeId: string, fieldName: string) => {
const dispatch = useAppDispatch();
const selector = useMemo(
() =>
createMemoizedSelector(
stateSelector,
({ nodes }) =>
nodes.mouseOverField?.nodeId === nodeId &&
nodes.mouseOverField?.fieldName === fieldName
),
[fieldName, nodeId]
);
const isMouseOverField = useAppSelector(selector);
const handleMouseOver = useCallback(() => {
dispatch(mouseOverFieldChanged({ nodeId, fieldName }));
}, [dispatch, fieldName, nodeId]);
const handleMouseOut = useCallback(() => {
dispatch(mouseOverFieldChanged(null));
}, [dispatch]);
return { isMouseOverField, handleMouseOver, handleMouseOut };
};

View File

@ -1,29 +1,24 @@
import { createMemoizedSelector } from 'app/store/createMemoizedSelector';
import { stateSelector } from 'app/store/store';
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
import { mouseOverNodeChanged } from 'features/nodes/store/nodesSlice';
import { useStore } from '@nanostores/react';
import { atom } from 'nanostores';
import { useCallback, useMemo } from 'react';
export const $mouseOverNode = atom<string | null>(null);
export const useMouseOverNode = (nodeId: string) => {
const dispatch = useAppDispatch();
const selector = useMemo(
() =>
createMemoizedSelector(
stateSelector,
({ nodes }) => nodes.mouseOverNode === nodeId
),
[nodeId]
const mouseOverNode = useStore($mouseOverNode);
const isMouseOverNode = useMemo(
() => mouseOverNode === nodeId,
[mouseOverNode, nodeId]
);
const isMouseOverNode = useAppSelector(selector);
const handleMouseOver = useCallback(() => {
!isMouseOverNode && dispatch(mouseOverNodeChanged(nodeId));
}, [dispatch, nodeId, isMouseOverNode]);
$mouseOverNode.set(nodeId);
}, [nodeId]);
const handleMouseOut = useCallback(() => {
isMouseOverNode && dispatch(mouseOverNodeChanged(null));
}, [dispatch, isMouseOverNode]);
$mouseOverNode.set(null);
}, []);
return { isMouseOverNode, handleMouseOver, handleMouseOut };
};