Home > Net >  Doesn't useEffect run after the component is rendered?
Doesn't useEffect run after the component is rendered?

Time:09-30

I am trying to set an event in useEffect:

useEffect(() => {
  var input = document.getElementById("emailInput");
  console.log(input); // null when reloading page!
  
  input.addEventListener("keyup", function(event) {
    console.log(event);
    if (event.key === 'Enter')
      onLogin();
  });
}, []);

Whenever I reload the page, the call to input.addEventListener fails because the value of input is null. It is my understanding that useEffect runs after the component is rendered, so the input element with id="emailInput" should already exist by then. What am I missing?

UPDATE: I was rendering the element conditionally based on something assigned in useEffect. I did not show that part in the question, but the part not shown was the problem...

CodePudding user response:

If you do not have other issues (like place of input field etc.), not removing event may cause this.

Try something like this to cleanup your event listener.

useEffect(() => {
    var input = document.getElementById("emailInput");
    console.log(input); // null when reloading page!

    const yourFunc = (event) => {
      console.log(event);
      if (event.key === 'Enter') console.log('hello')
    }
    
    input.addEventListener("keyup", yourFunc);

    return () => input.removeEventListener('keyup', yourFunc)
  }, []);

CodePudding user response:

What you are doing should work, so I suspect something like a spelling mistake.

However, as a general rule if emailInput is part of your React app, you should be storing a reference to the input in a ref.

const inputRef = useRef();

useEffect(() => {
  // do stuff with inputRef.current
}, [])

return <div><input ref={inputRef} /></div>

Even better, based on your example, and again if emailInput is part of your React app, you can simply add a onKeyUp directly as a prop. This way you can skip refs and useEffect

return <div><input onKeyUp={handleKeyUp} /></div>

CodePudding user response:

Yes useEffect runs after the component is rendered.

  • Related