useEffect
What is useEffect
Performs side effects
on your components.
Side effect
is a code that changes things outside the component
's return definition.
- e.g. setting
cookies
or modifyingHTML
.
useEffect(callback, dependency)
Also used to manage lifecycle of a component.
- When you define a function in a component, defined function is executed during the rendering phase of the component (not before or after the render).
useEffect
combines the functionality of componentDidMount
, componentDidUpdate
, componentWillUnmount
of Class React components.
dependency
useEffect
is used to run some sort of logic after the render
.
Used to call some logic specifically after a dependency is updated.
You can control when
these functions will be called and can get a guarantee that some functions will run after the rendering is complete (meaning, the DOM will be accessible).
useEffect(() => { // runs on every render }); useEffect(() => { // runs only on the first render }, []); useEffect(() => { // runs on the first render // and any time any dependency value changes }, [prop, state]); useEffect(() => { return () => { cleanup(); // cleanup function }; }, []);
Without dependencies, the useEffect
hook runs on mount and on every re-render.
With an array of dependencies, the useEffect
hook runs on mount and runs on subsequent renders when one or all of its dependencies change.
Dependency Array
With an empty array of dependencies, the useEffect
hook is called once on mount.
Without dependencies, the useEffect
hook runs on mount and on every re-render
With an array of dependencies, the useEffect
hook runs on mount and runs on subsequent renders when any of its dependencies change.
With an empty array of dependencies, the useEffect
Hook is called once on mount.
Infinite Re-render
If the variable referenced in the dependency array is NOT primitive, you will likely run into an infinite render loop:
- The
useEffect
internally compares the dependencies byreference
.
const [count, setCount] = useState(0); useEffect(() => { setCalculation(() => count * 2); }, [count]); // count is a primitive number variable const [someObj, setSomeObj] = useState({}); useEffect(() => { // new object passed every time with new address setSomeObj({field1: "this", field2: "that"}); }, [someObj])
Solution to infinite rendering problem:
const [someObj, setSomeObj] = useState({}); const { field1, field2 } = someObj; useEffect(() => { setSomeObj({field1: "this", field2: "that"}); }, [field1, field2]); // manually passing each field which is primitive