25

I'm new to Hooks and have been encountering some cases that have been sending me chasing my tail.

Hope someone can explain or provide solutions that make sense to me:

  1. Loading a method only once on mount of a component is confusing. I tried this method, it works, but don't understand it. Can someone explain this to me:

    const useMountEffect = fun => useEffect(fun, [])
    
    useMountEffect(() => {
      if (!isEdit) handleAddRow()
    })
    
    const handleAddRow = () => {
      let appendArr = [...listArr, '']
      setListArr(appendArr)
    }
    

Following this thread: How to call loading function with React useEffect only once

I tried just using useEffect without dependency and eslint does not like that and they recommend adding a skip next line which seems kind of hacky:

// eslint-disable-next-line
David Pell
  • 515
  • 1
  • 7
  • 14

2 Answers2

90

If I'm correct you want something similar to componentDidMount life-cycle method. The way to do that is

function MyComponent(props){
    useEffect(()=>{
        // do stuff here...
    }, []) // <-- empty dependency array
    return <div></div>
}

To understand what's happening you'll need to understand how the useEffect hooks work. Using the useEffect hook without any dependencies will trigger the effect every time some state or prop changes and causes a re-render. but if we pass an empty array as a dependency it will be as the effect not dependent on anything else, so it will only trigger when the component mounts.

Tridib Dawn
  • 159
  • 1
  • 9
Prithwee Das
  • 3,398
  • 13
  • 24
  • 24
    Why do so many people ask questions then not bother to return and reward the correct answer with a click on the answer as 'answered'? Seems very not nice to ask someone else's time w/o rewarding/thanking them. I see this all too often. How hard is it to return to a question and mark it? – Andrew H Jul 07 '20 at 18:18
  • this doesn't allow me to run an outside function once, cause I have to put the function inside the dependency array ... what do I do in those cases? – Kyle Calica-St Feb 02 '21 at 23:07
  • @KyleCalica-St If your function is defined outside of your components you don't need to pass it to the dependency array. – Prithwee Das Feb 03 '21 at 03:11
18

The empty array [] argument tells useEffect() to run only once

It will run only once on mount, like componentDidMount used to

Explanation:

useEffect() takes 2 arguments - your function and an array of dependencies

useEffect(
    yourFunction, // <- function that will run on every dependency update
    [] // <-- empty dependency array
) 

The dependency array argument tells it when to run your function. If the dependencies don't change it won't run again. If dependencies do update it will run your function again.

If you pass in an empty array (no dependencies) then the function will only run on mount.

ESLint missing dependency error

React Hook useEffect has a missing dependency: 'xxx'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

The reason for the ESLint rule is that useEffect() is designed to run on every dependency update it will expect you to add all the dependencies to that array.

To ignore this you can add above the dependency array line:

// eslint-disable-next-line react-hooks/exhaustive-deps
Jonathan Irwin
  • 3,531
  • 1
  • 18
  • 40
  • 2
    Thanks both for your response. 1. if you leave the useEffect() without a dependency you receive an eslint error. 2. When I use `const useMountEffect = fun => useEffect(fun, [])` method I don't receive an eslint error. Can someone explain why? – David Pell Sep 25 '19 at 18:21
  • 1
    @DavidPell the dependencies argument is not required (we can see that in the source here - https://github.com/facebook/react/blob/master/packages/react/src/ReactHooks.js#L96). The ESLint rule is just there to help you since you probably do want your function to only be run when it's inputs change. Dan Abv explains more in depth here https://overreacted.io/a-complete-guide-to-useeffect/ – Jonathan Irwin Sep 26 '19 at 06:47
  • Thanks for the articles, Jonathan! – David Pell Sep 26 '19 at 13:56
  • 1
    @DavidPell did this answer your question? If so can you mark it as accepted? – Jonathan Irwin Dec 11 '20 at 13:01