Home > Enterprise >  When I declare function in useEffect, it is not declared in html
When I declare function in useEffect, it is not declared in html

Time:01-13

I am implementing to change the state depending on it is hovered or not. But if I make it like the first code below, Too many re-renders. error will occur. In order to solve this problem, I used the useEffect to render only when the state changes, but an error called onHover is not defined occurs that the function declared in the user effect was not declared.

not using useEffect

import "./styles.css";
import { useState } from "react";

export default function App() {

  const [isHover, setIsHover] = useState(false);

  return (
    <button onm ouseEnter={setIsHover(true)} onm ouseLeave={setIsHover(false)}>
      click
    </button>
  );
}

using useEffect

import "./styles.css";
import { useEffect, useState } from "react";

export default function App() {

  const [isHover, setIsHover] = useState(false);

  useEffect(()=>{
    const onHover = () => {
      setIsHover(true)
    }
  },[isHover])

  return (
    <button onm ouseEnter={onHover()} onm ouseLeave={setIsHover(false)}>
      click
    </button>
  );
}

What should I do to use the function declared in useEffect?

CodePudding user response:

You need to pass a callback function that references the function you declared in useEffect, rather than calling the function directly.

Change this line:

<button onm ouseEnter={onHover()} onm ouseLeave={setIsHover(false)}>

To this:

<button onm ouseEnter={onHover} onm ouseLeave={() => setIsHover(false)}>

Also, you have to move the function outside of useEffect like this:

const onHover = () => {
    setIsHover(true)
}

useEffect(()=>{
  //do nothing
},[isHover])

This way, React will only call the function when the button is hovered over, rather than calling it during every render and causing too many re-renders.

CodePudding user response:

As you just want to setState so no need to use useEffect. You can use without using useEffect as below.

import "./styles.css";
import { useState } from "react";

export default function App() {

  const [isHover, setIsHover] = useState(false);

  return (
    <button onm ouseEnter={() => setIsHover(true)} onm ouseLeave={() => setIsHover(false)}>
      click
    </button>
  );
}

CodePudding user response:

It has to do with scope. The onHover function is defined within the useEffect hook, so it goes out of scope once you're out of the hook's block. You'll have to define it directly inside the component, outside of any other block scope, and simply call it inside useEffect.

It will still result in onHover called so many times until the mouse leaves the element in question. To prevent it, you could add a condition like so:

const onHover = () => {
  if (!isHover) {
    setIsHover(true);
  }
}
  • Related