React, functional components use variable used before defined, circular dependencies

Viewed 271

I have a problem with React functional components and React.useCallback and circular dependencies

see the following example code

import React from 'react'

export const FooBar = (props) => {

    const finish = React.useCallback((done) => {
        document.removeEventListener('mousemove', onMouseMove)
        document.removeEventListener('mouseup', onMouseUp)
    }, [onMouseMove, onMouseUp]) // here i get a problem as the variables are not defined yet

    const onMouseUp = React.useCallback((e) => {
        finish()
    }, [finish])

    const onMouseMove = React.useCallback((e) => {
        // update some stuff
    }, [])

    const onMouseDown = React.useCallback((e) => {
        document.addEventListener('mousemove', onMouseMove)
        document.addEventListener('mouseup', onMouseUp)
    }, [onMouseMove, onMouseUp])

    React.useEffect(() => {
        if (!props.map) {
            return
        }

        const canvas = props.map.getCanvas()
        canvas.addEventListener('mousedown', onMouseDown, true)
        return () => {
            canvas.removeEventListener('mousedown', onMouseDown, true)
        }
    }, [onMouseDown, props.map])

    return null
}

my problem is i can not move the code around that the variables are all defined before they are used in the deps-array. what would be a way to fix this with a functional component?

1 Answers

You could move all three into a memoized hook:

  const { finish, onMouseUp, onMouseDown } = useMemo(() => {
    function finish() {
       document.removeEventListener('mousemove', onMouseMove);
       document.removeEventListener('mouseup', onMouseUp);
    }
    function onMouseUp() { finish(); }
    function onMouseDown() { finish(); }

    return { finish, onMouseUp, onMouseDown };
  }, []);
Related