Skip to content

Commit

Permalink
fix: lint errors about hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
exuanbo committed Dec 3, 2023
1 parent a540e25 commit 9ea5031
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 30 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ const defaultConfig = {
},
],
'react-hooks/exhaustive-deps': [
'warn',
'error',
{
additionalHooks: '(useViewEffect)',
},
Expand Down
26 changes: 16 additions & 10 deletions src/common/components/ResizablePanel.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ReactNode, useEffect, useLayoutEffect, useRef, useState } from 'react'
import { ReactNode, useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'

import { clamp, classNames, range, throttle } from '../utils'

Expand All @@ -15,6 +15,8 @@ export interface ResizablePanelProps {
className?: string
}

const getOffsetWidth = (ref: React.RefObject<HTMLElement>) => ref.current!.offsetWidth

const ResizablePanel = ({
children: [leftChild, rightChild],
throttle: throttleMs = DEFAULT_RESIZE_THROTTLE_MS,
Expand All @@ -24,13 +26,17 @@ const ResizablePanel = ({
const dividerRef = useRef<HTMLDivElement>(null)
const rightChildRef = useRef<HTMLDivElement>(null)

const getDividerWidth = (): number => dividerRef.current!.offsetWidth

const getTotalWidth = (): number => containerRef.current!.offsetWidth - getDividerWidth()
const getTotalWidth = useCallback(
() => getOffsetWidth(containerRef) - getOffsetWidth(dividerRef),
[],
)

const getInitialLeftChildWidth = (): number => 0.5 * getTotalWidth()
const getInitialLeftChildWidth = useCallback(() => getTotalWidth() / 2, [getTotalWidth])

const getAvailableWidth = (): number => getTotalWidth() - rightChildRef.current!.offsetWidth
const getAvailableWidth = useCallback(
() => getTotalWidth() - getOffsetWidth(rightChildRef),
[getTotalWidth],
)

const [leftChildWidth, __setLeftChildWidth] = useState<number>()
const isReady = leftChildWidth !== undefined
Expand All @@ -44,7 +50,7 @@ const ResizablePanel = ({
if (!isReady) {
setLeftChildWidth(getInitialLeftChildWidth())
}
}, [isReady])
}, [getInitialLeftChildWidth, isReady])

useLayoutEffect(() => {
if (leftChildWidth !== undefined) {
Expand All @@ -53,7 +59,7 @@ const ResizablePanel = ({
setLeftChildWidth(availableWidth)
}
}
}, [leftChildWidth])
}, [getAvailableWidth, leftChildWidth])

const [isDragging, setDragging] = useState(false)

Expand Down Expand Up @@ -81,7 +87,7 @@ const ResizablePanel = ({
}

const handleMouseMove = throttle((event: MouseEvent) => {
const dividerWidth = getDividerWidth()
const dividerWidth = getOffsetWidth(dividerRef)
const clientX = event.clientX - dividerWidth / 2

const totalWidth = getTotalWidth()
Expand Down Expand Up @@ -112,7 +118,7 @@ const ResizablePanel = ({
document.removeEventListener('mousemove', handleMouseMove)
document.removeEventListener('mouseup', handleMouseUp)
}
}, [isDragging, throttleMs])
}, [getAvailableWidth, getTotalWidth, isDragging, throttleMs])

return (
<>
Expand Down
34 changes: 28 additions & 6 deletions src/common/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { RefCallback, useEffect, useReducer, useRef, useState } from 'react'
import {
RefCallback,
useCallback,
useEffect,
useInsertionEffect,
useReducer,
useRef,
useState,
} from 'react'

import { isFunction } from './utils/common'
import type { NonNullishValue } from './utils/types'
Expand All @@ -19,6 +27,21 @@ export const useSingleton = <T extends NonNullishValue>(instance: T | (() => T))

export const useRefCallback = <T>(): [T | null, RefCallback<T>] => useState<T | null>(null)

// https://github.com/SukkaW/foxact/blob/master/src/use-stable-handler-only-when-you-know-what-you-are-doing-or-you-will-be-fired/index.ts
export const useStableHandler = <A extends unknown[], R>(
callback: (...args: A) => R,
): typeof callback => {
const callbackRef = useRef<typeof callback>(null!)
useInsertionEffect(() => {
callbackRef.current = callback
}, [callback])

return useCallback<typeof callback>((...args) => {
const fn = callbackRef.current
return fn(...args)
}, [])
}

export const useOutsideClick = <T extends Element = Element>(
handler: (event: MouseEvent) => void,
): RefCallback<T> => {
Expand Down Expand Up @@ -59,10 +82,6 @@ export const useHover = <T extends Element = Element>(
isHovered: false,
})

const clearHoverTimeout = (): void => {
window.clearTimeout(mutableState.timeoutId)
}

useEffect(() => {
if (current === null) {
return
Expand All @@ -78,6 +97,9 @@ export const useHover = <T extends Element = Element>(
}, delay)
}
}
const clearHoverTimeout = (): void => {
window.clearTimeout(mutableState.timeoutId)
}
const handleMouseLeave = (): void => {
clearHoverTimeout()
handler(/* isHovered: */ false)
Expand All @@ -94,7 +116,7 @@ export const useHover = <T extends Element = Element>(
mutableState.isHovered = false
}
}
}, [current, handler, delay])
}, [current, delay, handler, mutableState])

return refCallback
}
2 changes: 1 addition & 1 deletion src/features/controller/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const Menu = ({ children }: Props): JSX.Element => {
setCurrentOpen(menuElement)
}
},
[currentOpen, menuElement],
[currentOpen, menuElement, setCurrentOpen],
)
const hoverRef = useHover(handleHover)

Expand Down
10 changes: 5 additions & 5 deletions src/features/controller/Toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useCallback, useMemo, useState } from 'react'

import Anchor from '@/common/components/Anchor'
import { Github } from '@/common/components/icons'
import { useOutsideClick } from '@/common/hooks'
import { useOutsideClick, useStableHandler } from '@/common/hooks'

import ConfigurationMenu from './ConfigurationMenu'
import ControlButtons from './ControlButtons'
Expand All @@ -14,21 +14,21 @@ import ViewMenu from './ViewMenu'
const ToolBar = (): JSX.Element => {
const [openMenu, __setOpenMenu] = useState<HTMLDivElement | null>(null)

const setOpenMenu = (element: HTMLDivElement | null): void => {
const setOpenMenu = useStableHandler((element: HTMLDivElement | null) => {
__setOpenMenu(element)
outsideClickRef(element)
}
})

const menuContextValue = useMemo(() => {
return {
currentOpen: openMenu,
setCurrentOpen: setOpenMenu,
}
}, [openMenu])
}, [openMenu, setOpenMenu])

const handleOutsideClick = useCallback(() => {
setOpenMenu(null)
}, [])
}, [setOpenMenu])
const outsideClickRef = useOutsideClick(handleOutsideClick)

return (
Expand Down
8 changes: 4 additions & 4 deletions src/features/controller/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ export const useController = (): Controller => {

useEffect(() => {
return subscribe(store.onAction(setEditorInput), controller.resetSelf)
}, [])
}, [controller])

useEffect(() => {
return subscribe(
Expand All @@ -428,11 +428,11 @@ export const useController = (): Controller => {
),
controller.assemble,
)
}, [])
}, [controller])

useEffect(() => {
return subscribe(store.onAction(setAssemblerState), controller.resetSelf)
}, [])
}, [controller])

useEffect(() => {
return subscribe(
Expand All @@ -445,7 +445,7 @@ export const useController = (): Controller => {
),
controller.stopAndRun,
)
}, [])
}, [controller])

return controller
}
2 changes: 1 addition & 1 deletion src/features/io/SevenSegmentDisplay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ const SevenSegmentDisplay = (): JSX.Element | null => {
}),
)
})
}, [])
}, [subscribeOutputData])

return isVisible ? (
<DeviceCard name="Seven-segment Display" onClose={toggleVisible}>
Expand Down
4 changes: 2 additions & 2 deletions src/features/io/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const useIoDevice = (deviceName: IoDeviceName): IoDevice => {
(listener: DataListener) => {
return subscribe(store.onState(selectData), listener)
},
[deviceName],
[selectData],
)

const selectVisibility = useMemo(() => selectIoDeviceVisibility(deviceName), [deviceName])
Expand All @@ -51,7 +51,7 @@ export const useIoDevice = (deviceName: IoDeviceName): IoDevice => {
toggleVisible,
)
}
}, [isVisible, deviceName])
}, [deviceName, isVisible, toggleVisible])

return { data, subscribeData, isVisible, toggleVisible }
}
Expand Down

0 comments on commit 9ea5031

Please sign in to comment.