skip to Main Content
useEffect(() => {
   console.log("change in focus")
}, [DEPENDENCY]);

I want a DEPENDENCY that changes when the focus changes in the document; an example would be when a user clicks on or off an input. I tried document.activeElement but it didn’t work.

2

Answers


  1. useEffect dependency arrays are only useful if your component is already rendering. You will need to write code that causes it to rerender. To be notified when focus changes you can use the focusin event. And if you want to render when this happens, you can set state.

    For example:

    const SomeComponent = () => {
      const [element, setElement] = useState(document.activeElement);
      useEffect(() => {
        const onFocusIn = (event => {
          console.log('focus changed', event.target);
          setElement(event.target);
        }
        document.addEventListener('focusin', onFocusIn)
        return () => document.removeEventListener('focusin', onFocusIn)
      }, []
    }
    

    You may also want to listen to the focusout event.

    Login or Signup to reply.
  2. You can’t directly use document.activeElement as a dependency in useEffect because useEffect dependencies must be values that can change and trigger a re-render, not side-effect operations like event handling.

    import React, { useState, useEffect, useRef } from 'react';
    
    export default function App() {
      const [inputFocus, setInputFocus] = useState(false);
      const inputRef = useRef(null);
    
      useEffect(() => {
        const inputElement = inputRef.current;
    
        if (inputElement) {
          const handleFocus = () => setInputFocus(true);
          const handleBlur = () => setInputFocus(false);
    
          // Add event listeners
          inputElement.addEventListener('focus', handleFocus);
          inputElement.addEventListener('blur', handleBlur);
    
          // Cleanup event listeners on component unmount
          return () => {
            inputElement.removeEventListener('focus', handleFocus);
            inputElement.removeEventListener('blur', handleBlur);
          };
        }
      }, []);
    
      useEffect(() => {
        console.log(`Input focus changed: ${inputFocus}`);
      }, [inputFocus]);
    
      return (
        <div>
          <h1>{inputFocus ? "Input is focused" : "Input is not focused"}</h1>
          <input ref={inputRef} type="text" placeholder="Click here or outside to change focus" />
        </div>
      );
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search