Search code examples
reactjsreact-hookskeyboard-events

Not able to Call useCallback function on KeyDown


            <span
              key="next"
              aria-label={"Next"}
              // ref={NextPageButtonRef}
              onClick={changeHandler(!hasNext, page + 1)}
              onKeyDown={(e) => {
                if (e.key === "Enter") {
                    changeHandler(!hasNext, page + 1);
                }
              }
              tabIndex={0}
            >
              <span>Next</span>
            </span>
 const changeHandler = useCallback(
    (exitEarly: boolean, target: number) => () => {
      if (target === page || exitEarly) {
        return;
      }

      onPageChange(clamp(target, 1, count as number));
    },
    [onPageChange, page, count]
  );

Actually I want to call "changeHandler" when Enter is pressed

It works when I call it directly like this

onKeyDown = {changeHandler(!hasNext, page + 1)}

but I want it to only call when Enter is pressed


Solution

  • You're useCallback has a function that returns a function. So when calling changeHandler in the onKeyDown handler it will not execute the function where you do the check and fire onPageChange

    You can solve this by removing the extra function

    const changeHandler = useCallback(
        (exitEarly: boolean, target: number) => {
            if (target === page || exitEarly) {
                return;
            }
    
            onPageChange(clamp(target, 1, count as number));
        },
        [onPageChange, page, count],
    );
    

    Then the onClick need to have a anonymous function since the changeHandler does not return a function anymore it will invoke immediately.

    <span
      key="next"
      aria-label={"Next"}
      // ref={NextPageButtonRef}
      onClick={() => changeHandler(!hasNext, page + 1)}
      onKeyDown={(e) => {
        if (e.key === "Enter") {
            changeHandler(!hasNext, page + 1);
        }
      }
      tabIndex={0}
    >
      <span>Next</span>
    </span>