javascriptreactjsuse-effectonfocususe-ref

onFocus react with hotkeys to focus on elements anywhere on page


I am trying to create hotkeys using shift + number to focus in on an element on my webpage. In JavaScript you use .focus() after targeting the element but in react I am confused. I have about 5 components that need to be focused in on hotkey press. I have code currently that is able to run on the key press, and also run a function but then I don't know how to progress.

I know the onFocus will only run when I tab or click on the input here... but I didnt know how to do like a conditional synthetic event. As in hotkeypress? onFocus : null


//app.js

 function useKey(key, cb) {
    const callbackRef = useRef(cb);

    useEffect(() => {
      callbackRef.current = cb;
    });

    useEffect(() => {
      function hotkeyPress(e) {
        if (e.shiftKey && e.keyCode === key) {
          callbackRef.current(e);
        }
      }

      document.addEventListener('keydown', hotkeyPress);
      return () => document.removeEventListener('keydown', hotkeyPress);
    }, [key]);
  }

 <ContactInfo
          searchValue={searchValue}
          handleSearchChange={handleSearchChange}
          onSearchCloseClick={onSearchCloseClick}
          onSearchClick={onSearchClick}
          useKey={useKey}
        />
    

//component to use

 function handleKeypress() {
    //?
  }

 <input
        className='contactSearchForm__input'
        placeholder='Customer name/number'
        type='text'
        list='searchList'
        value={searchValue}
        onChange={handleSearchChange}
        onFocus={useKey(49, handleKeypress)}
      />


Solution

  • So I was doing a little bit too much. This is all you need to target and focus different elements with hotkeys on a page using React. I ended up changing it to f keys but you can also do shift + number or any other key.

    //app.js
     function useKey(key, ref) {
        useEffect(() => {
          function hotkeyPress(e) {
            if (e.keyCode === key) {
              e.preventDefault();
              ref.current.focus();
              return;
            }
          }
    
          document.addEventListener('keydown', hotkeyPress);
          return () => document.removeEventListener('keydown', hotkeyPress);
        }, [key]);
      }
    
    //component to use
    const f1Ref = useRef();
      useKey(112, f1Ref);
    
          <input
            className='contactSearchForm__input'
            placeholder='Customer name/number'
            type='text'
            list='searchList'
            value={searchValue}
            onChange={handleSearchChange}
            ref={f1Ref}
          />