Reputation: 939
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:
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
Upvotes: 61
Views: 150939
Reputation: 5226
If I'm correct you want something similar to the 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
hook works.
Using the useEffect
hook without any dependencies will trigger the effect every time some state or prop changes and causes a re-render;
however, if we pass an empty array as a dependency it will mark the effect as not dependent on anything else, so it will only trigger when the component mounts.
Upvotes: 190
Reputation: 5747
[]
argument tells useEffect() to run only onceIt will run only once on mount, like componentDidMount
used to
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.
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.
// eslint-disable-next-line react-hooks/exhaustive-deps
Note: You almost never want to ignore the error
Note that on React 18 Strict Mode + Dev mode useEffect()
will be called twice - read more about it here
Upvotes: 47
Reputation: 2180
For anyone looking to execute a function once per whole App (globally), this could be a solution:
if (typeof window !== 'undefined') { // Check if we're running in the browser.
// ✅ Only runs once per app load
checkAuthToken();
loadDataFromLocalStorage();
}
function App() {
// ...
}
Source / extended explanation here.
Upvotes: 12