Merged PR 165: Move useEffects to named functions

Move useEffects to named functions
This commit is contained in:
Eric Nguyen 2022-08-22 15:52:40 +00:00
parent 29625dce28
commit ec3fddec9d
6 changed files with 150 additions and 91 deletions

View file

@ -1,4 +1,4 @@
import React, { useRef } from 'react'; import React, { Dispatch, SetStateAction, useEffect, useRef } from 'react';
import './Editor.scss'; import './Editor.scss';
import { IConfiguration } from '../../Interfaces/IConfiguration'; import { IConfiguration } from '../../Interfaces/IConfiguration';
import { SVG } from '../SVG/SVG'; import { SVG } from '../SVG/SVG';
@ -36,12 +36,12 @@ export const getCurrentHistory = (history: IHistoryState[], historyCurrentStep:
export const getCurrentHistoryState = (history: IHistoryState[], historyCurrentStep: number): IHistoryState => history[historyCurrentStep]; export const getCurrentHistoryState = (history: IHistoryState[], historyCurrentStep: number): IHistoryState => history[historyCurrentStep];
const Editor: React.FunctionComponent<IEditorProps> = (props) => { function useShortcuts(
const [history, setHistory] = React.useState<IHistoryState[]>(structuredClone(props.history)); history: IHistoryState[],
const [historyCurrentStep, setHistoryCurrentStep] = React.useState<number>(props.historyCurrentStep); historyCurrentStep: number,
const editorRef = useRef<HTMLDivElement>(null); setHistoryCurrentStep: Dispatch<SetStateAction<number>>
): void {
React.useEffect(() => { useEffect(() => {
const onKeyUp = (event: KeyboardEvent): void => onKeyDown( const onKeyUp = (event: KeyboardEvent): void => onKeyDown(
event, event,
history, history,
@ -50,12 +50,24 @@ const Editor: React.FunctionComponent<IEditorProps> = (props) => {
); );
window.addEventListener('keyup', onKeyUp); window.addEventListener('keyup', onKeyUp);
return () => {
window.removeEventListener('keyup', onKeyUp);
};
});
}
function useWindowEvents(
history: IHistoryState[],
historyCurrentStep: number,
configuration: IConfiguration,
editorRef: React.RefObject<HTMLDivElement>
): void {
useEffect(() => {
const events = EditorEvents; const events = EditorEvents;
const editorState: IEditorState = { const editorState: IEditorState = {
history, history,
historyCurrentStep, historyCurrentStep,
configuration: props.configuration configuration
}; };
const funcs = new Map<string, () => void>(); const funcs = new Map<string, () => void>();
@ -64,10 +76,7 @@ const Editor: React.FunctionComponent<IEditorProps> = (props) => {
editorRef.current?.addEventListener(event.name, func); editorRef.current?.addEventListener(event.name, func);
funcs.set(event.name, func); funcs.set(event.name, func);
} }
return () => { return () => {
window.removeEventListener('keyup', onKeyUp);
for (const event of events) { for (const event of events) {
const func = funcs.get(event.name); const func = funcs.get(event.name);
if (func === undefined) { if (func === undefined) {
@ -77,6 +86,15 @@ const Editor: React.FunctionComponent<IEditorProps> = (props) => {
} }
}; };
}); });
}
const Editor: React.FunctionComponent<IEditorProps> = (props) => {
const [history, setHistory] = React.useState<IHistoryState[]>(structuredClone(props.history));
const [historyCurrentStep, setHistoryCurrentStep] = React.useState<number>(props.historyCurrentStep);
const editorRef = useRef<HTMLDivElement>(null);
useShortcuts(history, historyCurrentStep, setHistoryCurrentStep);
useWindowEvents(history, historyCurrentStep, props.configuration, editorRef);
const configuration = props.configuration; const configuration = props.configuration;
const current = getCurrentHistoryState(history, historyCurrentStep); const current = getCurrentHistoryState(history, historyCurrentStep);

View file

@ -5,9 +5,10 @@ import { IContainerModel } from '../../Interfaces/IContainerModel';
import { getDepth, MakeIterator } from '../../utils/itertools'; import { getDepth, MakeIterator } from '../../utils/itertools';
import { Menu } from '../Menu/Menu'; import { Menu } from '../Menu/Menu';
import { MenuItem } from '../Menu/MenuItem'; import { MenuItem } from '../Menu/MenuItem';
import { handleDragLeave, handleDragOver, handleLeftClick, handleOnDrop, handleRightClick } from './MouseEventHandlers'; import { handleDragLeave, handleDragOver, handleLeftClick, handleOnDrop, handleRightClick, useMouseEvents } from './MouseEventHandlers';
import { IPoint } from '../../Interfaces/IPoint'; import { IPoint } from '../../Interfaces/IPoint';
import { ISymbolModel } from '../../Interfaces/ISymbolModel'; import { ISymbolModel } from '../../Interfaces/ISymbolModel';
import { Dispatch, RefObject, SetStateAction } from 'react';
interface IElementsSidebarProps { interface IElementsSidebarProps {
MainContainer: IContainerModel MainContainer: IContainerModel
@ -33,42 +34,13 @@ export const ElementsSidebar: React.FC<IElementsSidebarProps> = (props: IElement
const elementRef = React.useRef<HTMLDivElement>(null); const elementRef = React.useRef<HTMLDivElement>(null);
// Event listeners // Event listeners
React.useEffect(() => { useMouseEvents(
const onContextMenu = (event: MouseEvent): void => handleRightClick( isContextMenuOpen,
event, elementRef,
setIsContextMenuOpen, setIsContextMenuOpen,
setOnClickContainerId, setOnClickContainerId,
setContextMenuPosition setContextMenuPosition
); );
const onLeftClick = (): void => handleLeftClick(
isContextMenuOpen,
setIsContextMenuOpen,
setOnClickContainerId
);
elementRef.current?.addEventListener(
'contextmenu',
onContextMenu
);
window.addEventListener(
'click',
onLeftClick
);
return () => {
elementRef.current?.removeEventListener(
'contextmenu',
onContextMenu
);
window.removeEventListener(
'click',
onLeftClick
);
};
});
// Render // Render
let isOpenClasses = '-right-64'; let isOpenClasses = '-right-64';

View file

@ -1,7 +1,53 @@
import React, { RefObject, Dispatch, SetStateAction, useEffect } from 'react';
import { IContainerModel } from '../../Interfaces/IContainerModel'; import { IContainerModel } from '../../Interfaces/IContainerModel';
import { IPoint } from '../../Interfaces/IPoint'; import { IPoint } from '../../Interfaces/IPoint';
import { findContainerById } from '../../utils/itertools'; import { findContainerById } from '../../utils/itertools';
export function useMouseEvents(
isContextMenuOpen: boolean,
elementRef: RefObject<HTMLDivElement>,
setIsContextMenuOpen: Dispatch<SetStateAction<boolean>>,
setOnClickContainerId: Dispatch<SetStateAction<string>>,
setContextMenuPosition: Dispatch<SetStateAction<IPoint>>
): void {
useEffect(() => {
const onContextMenu = (event: MouseEvent): void => handleRightClick(
event,
setIsContextMenuOpen,
setOnClickContainerId,
setContextMenuPosition
);
const onLeftClick = (): void => handleLeftClick(
isContextMenuOpen,
setIsContextMenuOpen,
setOnClickContainerId
);
elementRef.current?.addEventListener(
'contextmenu',
onContextMenu
);
window.addEventListener(
'click',
onLeftClick
);
return () => {
elementRef.current?.removeEventListener(
'contextmenu',
onContextMenu
);
window.removeEventListener(
'click',
onLeftClick
);
};
});
}
export function handleRightClick( export function handleRightClick(
event: MouseEvent, event: MouseEvent,
setIsContextMenuOpen: React.Dispatch<React.SetStateAction<boolean>>, setIsContextMenuOpen: React.Dispatch<React.SetStateAction<boolean>>,

View file

@ -33,12 +33,9 @@ function resizeViewBox(
}); });
} }
export const SVG: React.FC<ISVGProps> = (props: ISVGProps) => { function useSVGAutoResizer(
const [viewer, setViewer] = React.useState<Viewer>({ setViewer: React.Dispatch<React.SetStateAction<Viewer>>
viewerWidth: window.innerWidth - BAR_WIDTH, ): void {
viewerHeight: window.innerHeight
});
React.useEffect(() => { React.useEffect(() => {
const onResize = (): void => resizeViewBox(setViewer); const onResize = (): void => resizeViewBox(setViewer);
window.addEventListener('resize', onResize); window.addEventListener('resize', onResize);
@ -47,6 +44,15 @@ export const SVG: React.FC<ISVGProps> = (props: ISVGProps) => {
window.removeEventListener('resize', onResize); window.removeEventListener('resize', onResize);
}; };
}); });
}
export const SVG: React.FC<ISVGProps> = (props: ISVGProps) => {
const [viewer, setViewer] = React.useState<Viewer>({
viewerWidth: window.innerWidth - BAR_WIDTH,
viewerHeight: window.innerHeight
});
useSVGAutoResizer(setViewer);
const xmlns = '<http://www.w3.org/2000/svg>'; const xmlns = '<http://www.w3.org/2000/svg>';
const properties = { const properties = {

View file

@ -1,5 +1,51 @@
import { RefObject, Dispatch, SetStateAction, useEffect } from 'react';
import { IPoint } from '../../Interfaces/IPoint'; import { IPoint } from '../../Interfaces/IPoint';
export function useMouseEvents(
isContextMenuOpen: boolean,
elementRef: RefObject<HTMLDivElement>,
setIsContextMenuOpen: Dispatch<SetStateAction<boolean>>,
setOnClickSymbolId: Dispatch<SetStateAction<string>>,
setContextMenuPosition: Dispatch<SetStateAction<IPoint>>
): void {
useEffect(() => {
const onContextMenu = (event: MouseEvent): void => handleRightClick(
event,
setIsContextMenuOpen,
setOnClickSymbolId,
setContextMenuPosition
);
const onLeftClick = (): void => handleLeftClick(
isContextMenuOpen,
setIsContextMenuOpen,
setOnClickSymbolId
);
elementRef.current?.addEventListener(
'contextmenu',
onContextMenu
);
window.addEventListener(
'click',
onLeftClick
);
return () => {
elementRef.current?.removeEventListener(
'contextmenu',
onContextMenu
);
window.removeEventListener(
'click',
onLeftClick
);
};
});
}
export function handleRightClick( export function handleRightClick(
event: MouseEvent, event: MouseEvent,
setIsContextMenuOpen: React.Dispatch<React.SetStateAction<boolean>>, setIsContextMenuOpen: React.Dispatch<React.SetStateAction<boolean>>,

View file

@ -2,7 +2,7 @@ import * as React from 'react';
import { FixedSizeList as List } from 'react-window'; import { FixedSizeList as List } from 'react-window';
import { Menu } from '../Menu/Menu'; import { Menu } from '../Menu/Menu';
import { MenuItem } from '../Menu/MenuItem'; import { MenuItem } from '../Menu/MenuItem';
import { handleLeftClick, handleRightClick } from './MouseEventHandlers'; import { handleLeftClick, handleRightClick, useMouseEvents } from './MouseEventHandlers';
import { IPoint } from '../../Interfaces/IPoint'; import { IPoint } from '../../Interfaces/IPoint';
import { ISymbolModel } from '../../Interfaces/ISymbolModel'; import { ISymbolModel } from '../../Interfaces/ISymbolModel';
import { SymbolProperties } from '../SymbolProperties/SymbolProperties'; import { SymbolProperties } from '../SymbolProperties/SymbolProperties';
@ -29,42 +29,13 @@ export const SymbolsSidebar: React.FC<ISymbolsSidebarProps> = (props: ISymbolsSi
const elementRef = React.useRef<HTMLDivElement>(null); const elementRef = React.useRef<HTMLDivElement>(null);
// Event listeners // Event listeners
React.useEffect(() => { useMouseEvents(
const onContextMenu = (event: MouseEvent): void => handleRightClick( isContextMenuOpen,
event, elementRef,
setIsContextMenuOpen, setIsContextMenuOpen,
setOnClickSymbolId, setOnClickSymbolId,
setContextMenuPosition setContextMenuPosition
); );
const onLeftClick = (): void => handleLeftClick(
isContextMenuOpen,
setIsContextMenuOpen,
setOnClickSymbolId
);
elementRef.current?.addEventListener(
'contextmenu',
onContextMenu
);
window.addEventListener(
'click',
onLeftClick
);
return () => {
elementRef.current?.removeEventListener(
'contextmenu',
onContextMenu
);
window.removeEventListener(
'click',
onLeftClick
);
};
});
// Render // Render
let isOpenClasses = '-right-64'; let isOpenClasses = '-right-64';