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
cookiesor 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
useEffectinternally 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