{"type_of":"article","id":718222,"title":"React useEffect: The basics and the secrets","description":"Almost everyone is familiar with hooks these days, useEffect is one of the most used hook. My 2 cents...","readable_publish_date":"Jun 4 '21","slug":"useeffect-the-basics-and-the-secrets-4ehg","path":"/mukuljainx/useeffect-the-basics-and-the-secrets-4ehg","url":"https://dev.to/mukuljainx/useeffect-the-basics-and-the-secrets-4ehg","comments_count":0,"public_reactions_count":82,"collection_id":null,"published_timestamp":"2021-06-04T16:55:56Z","language":"en","subforem_id":null,"positive_reactions_count":82,"cover_image":"https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2nsz94qwt2tipdbqdiq.png","social_image":"https://media2.dev.to/dynamic/image/width=1000,height=500,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2nsz94qwt2tipdbqdiq.png","canonical_url":"https://dev.to/mukuljainx/useeffect-the-basics-and-the-secrets-4ehg","created_at":"2021-06-04T16:42:59Z","edited_at":"2021-06-05T05:59:47Z","crossposted_at":null,"published_at":"2021-06-04T16:55:56Z","last_comment_at":"2021-06-04T16:55:56Z","reading_time_minutes":2,"tag_list":"react, javascript, weeklyui, tutorial","tags":["react","javascript","weeklyui","tutorial"],"body_html":"\u003cp\u003eAlmost everyone is familiar with hooks these days, \u003ccode\u003euseEffect\u003c/code\u003e is one of the most used hook. My 2 cents on it!\u003c/p\u003e\n\n\u003cp\u003eIt's a hook which triggers after each render to perform any side effect.\u003c/p\u003e\n\n\u003ch3\u003e\n  \u003ca name=\"simple-useeffect\" href=\"#simple-useeffect\"\u003e\n  \u003c/a\u003e\n  Simple useEffect\n\u003c/h3\u003e\n\n\n\n\u003cdiv class=\"highlight js-code-highlight\"\u003e\n\u003cpre class=\"highlight jsx\"\u003e\u003ccode\u003e\u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003esetCount\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003euseState\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\n\u003cspan class=\"nf\"\u003euseEffect\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n  \u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etitle\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\n\u003c/code\u003e\u003c/pre\u003e\n\u003cdiv class=\"highlight__panel js-actions-panel\"\u003e\n\u003cdiv class=\"highlight__panel-action js-fullscreen-code-action\"\u003e\n    \u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"\u003e\u003ctitle\u003eEnter fullscreen mode\u003c/title\u003e\n    \u003cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\u003e\u003c/path\u003e\n\u003c/svg\u003e\n\n    \u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"\u003e\u003ctitle\u003eExit fullscreen mode\u003c/title\u003e\n    \u003cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\u003e\u003c/path\u003e\n\u003c/svg\u003e\n\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\n\n\n\u003cp\u003eWhenever the components re-render the hook will trigger updating the document title. It might be due to count change or its parent might have re-rendered causing this to re-render.\u003c/p\u003e\n\n\u003ch3\u003e\n  \u003ca name=\"the-cleanup-method\" href=\"#the-cleanup-method\"\u003e\n  \u003c/a\u003e\n  The Cleanup Method\n\u003c/h3\u003e\n\n\u003cp\u003eIf you are creating side effect, you might want to clear them like clearing \u003ccode\u003etimeout\u003c/code\u003e or cancelling previous pending API request, for this we have cleanup method, return a function from useEffect and it will trigger at unmount or before the next cycle of the same useEffect.\u003cbr\u003e\n\u003c/p\u003e\n\n\u003cdiv class=\"highlight js-code-highlight\"\u003e\n\u003cpre class=\"highlight jsx\"\u003e\u003ccode\u003e\u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"nx\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003esetCount\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003euseState\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\n\u003cspan class=\"nf\"\u003euseEffect\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n  \u003cspan class=\"c1\"\u003e// Not a good practice, just for the sake of example\u003c/span\u003e\n  \u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ebody\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ebackground\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"dl\"\u003e'\u003c/span\u003e\u003cspan class=\"s1\"\u003ered\u003c/span\u003e\u003cspan class=\"dl\"\u003e'\u003c/span\u003e\n    \u003cspan class=\"k\"\u003ereturn \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n      \u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ebody\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ebackground\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"dl\"\u003e'\u003c/span\u003e\u003cspan class=\"s1\"\u003eblue\u003c/span\u003e\u003cspan class=\"dl\"\u003e'\u003c/span\u003e\n    \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\n\u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\n\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nx\"\u003ebutton\u003c/span\u003e \u003cspan class=\"nx\"\u003eonClick\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"p\"\u003e{()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"nf\"\u003esetCount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ecount\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)}\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"nx\"\u003eCount\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"err\"\u003e/\u003c/span\u003e\u003cspan class=\"na\"\u003ebutton\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\n\u003c/code\u003e\u003c/pre\u003e\n\u003cdiv class=\"highlight__panel js-actions-panel\"\u003e\n\u003cdiv class=\"highlight__panel-action js-fullscreen-code-action\"\u003e\n    \u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"\u003e\u003ctitle\u003eEnter fullscreen mode\u003c/title\u003e\n    \u003cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\u003e\u003c/path\u003e\n\u003c/svg\u003e\n\n    \u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"\u003e\u003ctitle\u003eExit fullscreen mode\u003c/title\u003e\n    \u003cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\u003e\u003c/path\u003e\n\u003c/svg\u003e\n\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\n\n\n\u003cp\u003eMost people learn \u003ccode\u003euseEffect\u003c/code\u003e by relating it to \u003ccode\u003ecomponentDidMount\u003c/code\u003e, \u003ccode\u003ecomponentDidUpdate\u003c/code\u003e and \u003ccode\u003ecomponentWillUnmount\u003c/code\u003e. So they relates the cleanup function with \u003ccode\u003ecomponentWillUnmount\u003c/code\u003e and thinks all cleanup are triggered only once, on unmount. Which is far from the truth! whenever I asked this question in interview only answer I got was \"in the unmount phase\"\u003c/p\u003e\n\n\u003cp\u003eAfter the first render \u003ccode\u003euseEffect\u003c/code\u003e will trigger and we can see background color as red and when the state changes the component will re-render hence \u003ccode\u003euseEffect\u003c/code\u003e will trigger again after the render but before that, cleanup method will trigger as shown in this gif.\u003c/p\u003e\n\n\u003cp\u003e\u003ca href=\"https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nwtya5qdl9hlqbe8jew.gif\" class=\"article-body-image-wrapper\"\u003e\u003cimg src=\"https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6nwtya5qdl9hlqbe8jew.gif\" alt=\"useEffect Demo\" loading=\"lazy\"\u003e\u003c/a\u003e\u003c/p\u003e\n\n\u003cp\u003e\u003cstrong\u003eWhy?\u003c/strong\u003e: To keep the concern limited at one place, Assume cleanup doesn't run before every useEffect and let's say you are using \u003ccode\u003esetTimeout\u003c/code\u003e in the \u003ccode\u003euseEffect\u003c/code\u003e, if there is second \u003ccode\u003euseEffect\u003c/code\u003e call you have to cancel the first timer or there might be a memory leak, a possible way to do it is\u003cbr\u003e\n\u003c/p\u003e\n\n\u003cdiv class=\"highlight js-code-highlight\"\u003e\n\u003cpre class=\"highlight jsx\"\u003e\u003ccode\u003e\u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003etimer\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eReact\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nf\"\u003euseRef\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kc\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\n\u003cspan class=\"nf\"\u003euseEffect\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n  \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etimer\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecurrent\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\n    \u003cspan class=\"nf\"\u003eclearTimeout\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etimer\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecurrent\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n  \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\n  \u003cspan class=\"nx\"\u003etimer\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecurrent\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003esetTimeout\u003c/span\u003e\u003cspan class=\"p\"\u003e(...\u003c/span\u003e\n\u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/code\u003e\u003c/pre\u003e\n\u003cdiv class=\"highlight__panel js-actions-panel\"\u003e\n\u003cdiv class=\"highlight__panel-action js-fullscreen-code-action\"\u003e\n    \u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"\u003e\u003ctitle\u003eEnter fullscreen mode\u003c/title\u003e\n    \u003cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\u003e\u003c/path\u003e\n\u003c/svg\u003e\n\n    \u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"\u003e\u003ctitle\u003eExit fullscreen mode\u003c/title\u003e\n    \u003cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\u003e\u003c/path\u003e\n\u003c/svg\u003e\n\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\n\n\n\u003cp\u003ebut with a cleanup function you can do\u003cbr\u003e\n\u003c/p\u003e\n\n\u003cdiv class=\"highlight js-code-highlight\"\u003e\n\u003cpre class=\"highlight plaintext\"\u003e\u003ccode\u003euseEffect(() =\u0026gt; {\n  const timer = setTimeout(...\n\n  return () =\u0026gt; {\n    clearTimeout(timer);\n  }\n})\n\u003c/code\u003e\u003c/pre\u003e\n\u003cdiv class=\"highlight__panel js-actions-panel\"\u003e\n\u003cdiv class=\"highlight__panel-action js-fullscreen-code-action\"\u003e\n    \u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"\u003e\u003ctitle\u003eEnter fullscreen mode\u003c/title\u003e\n    \u003cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\u003e\u003c/path\u003e\n\u003c/svg\u003e\n\n    \u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"\u003e\u003ctitle\u003eExit fullscreen mode\u003c/title\u003e\n    \u003cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\u003e\u003c/path\u003e\n\u003c/svg\u003e\n\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\n\n\n\u003ch3\u003e\n  \u003ca name=\"optimize-using-the-dependency-array\" href=\"#optimize-using-the-dependency-array\"\u003e\n  \u003c/a\u003e\n  Optimize using the dependency array\n\u003c/h3\u003e\n\n\u003cp\u003eThere might be a case where you don't want it to run every time but on specific condition for this useEffect (all the hooks) have another parameter known as dependency array, where you can specify the dependent parameter like \u003ccode\u003e[count]\u003c/code\u003e, useEffect will trigger only if \u003ccode\u003ecount\u003c/code\u003e changes and cleanup method too.\u003c/p\u003e\n\n\u003ch3\u003e\n  \u003ca name=\"empty-dependency-array\" href=\"#empty-dependency-array\"\u003e\n  \u003c/a\u003e\n  Empty dependency array\n\u003c/h3\u003e\n\n\u003cp\u003eIs it a special case for \u003ccode\u003ecomponentWillunmount\u003c/code\u003e and \u003ccode\u003ecomponentDidMount\u003c/code\u003e? Nope, though it seems like but it is not handled separately.\u003cbr\u003e\n\u003c/p\u003e\n\n\u003cdiv class=\"highlight js-code-highlight\"\u003e\n\u003cpre class=\"highlight plaintext\"\u003e\u003ccode\u003euseEffect(() =\u0026gt; {\n  ...\n  return () =\u0026gt; {...}\n}, [])\n\u003c/code\u003e\u003c/pre\u003e\n\u003cdiv class=\"highlight__panel js-actions-panel\"\u003e\n\u003cdiv class=\"highlight__panel-action js-fullscreen-code-action\"\u003e\n    \u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-on\"\u003e\u003ctitle\u003eEnter fullscreen mode\u003c/title\u003e\n    \u003cpath d=\"M16 3h6v6h-2V5h-4V3zM2 3h6v2H4v4H2V3zm18 16v-4h2v6h-6v-2h4zM4 19h4v2H2v-6h2v4z\"\u003e\u003c/path\u003e\n\u003c/svg\u003e\n\n    \u003csvg xmlns=\"http://www.w3.org/2000/svg\" width=\"20px\" height=\"20px\" viewbox=\"0 0 24 24\" class=\"highlight-action crayons-icon highlight-action--fullscreen-off\"\u003e\u003ctitle\u003eExit fullscreen mode\u003c/title\u003e\n    \u003cpath d=\"M18 7h4v2h-6V3h2v4zM8 9H2V7h4V3h2v6zm10 8v4h-2v-6h6v2h-4zM8 15v6H6v-4H2v-2h6z\"\u003e\u003c/path\u003e\n\u003c/svg\u003e\n\n\u003c/div\u003e\n\u003c/div\u003e\n\u003c/div\u003e\n\n\n\n\u003cp\u003e\u003ccode\u003e[]\u003c/code\u003e means no dependency, so useEffect will trigger only during the initial render and cleanup only in unmount phase, React calls all cleanup methods in unmount phase hence it will run, so it behaves same way as \u003ccode\u003ecomponentWillunmount\u003c/code\u003e and \u003ccode\u003ecomponentDidMount\u003c/code\u003e but it's not the same.\u003c/p\u003e\n\n\u003cp\u003eLast but not least due to closure cleanup will have values of previous state when \u003ccode\u003euseEffect\u003c/code\u003e was executed.\u003c/p\u003e\n\n\u003cp\u003eYou can play with \u003ccode\u003euseEffect\u003c/code\u003e \u003ca href=\"https://codesandbox.io/s/understanding-use-effect-hx83v\" target=\"_blank\" rel=\"noopener noreferrer\"\u003ehere\u003c/a\u003e \u003c/p\u003e\n\n","body_markdown":"Almost everyone is familiar with hooks these days, `useEffect` is one of the most used hook. My 2 cents on it!\n\nIt's a hook which triggers after each render to perform any side effect.\n\n### Simple useEffect\n\n```jsx\nconst [count, setCount] = useState(0)\n\nuseEffect(() =\u003e {\n  document.title = count;\n})\n\n```\n\nWhenever the components re-render the hook will trigger updating the document title. It might be due to count change or its parent might have re-rendered causing this to re-render.\n\n\n### The Cleanup Method\n\nIf you are creating side effect, you might want to clear them like clearing `timeout` or cancelling previous pending API request, for this we have cleanup method, return a function from useEffect and it will trigger at unmount or before the next cycle of the same useEffect.\n\n\n```jsx\nconst [count, setCount] = useState(0)\n\nuseEffect(() =\u003e {\n  // Not a good practice, just for the sake of example\n  document.body.style.background = 'red'\n    return () =\u003e {\n      document.body.style.background = 'blue'\n    };\n})\n\n...\n\n\u003cbutton onClick={() =\u003e setCount(count+1)}\u003eCount ++\u003c/button\u003e\n\n```\n\nMost people learn `useEffect` by relating it to `componentDidMount`, `componentDidUpdate` and `componentWillUnmount`. So they relates the cleanup function with `componentWillUnmount` and thinks all cleanup are triggered only once, on unmount. Which is far from the truth! whenever I asked this question in interview only answer I got was \"in the unmount phase\"\n\nAfter the first render `useEffect` will trigger and we can see background color as red and when the state changes the component will re-render hence `useEffect` will trigger again after the render but before that, cleanup method will trigger as shown in this gif.\n\n\n![useEffect Demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6nwtya5qdl9hlqbe8jew.gif)\n\n**Why?**: To keep the concern limited at one place, Assume cleanup doesn't run before every useEffect and let's say you are using `setTimeout` in the `useEffect`, if there is second `useEffect` call you have to cancel the first timer or there might be a memory leak, a possible way to do it is\n\n```jsx\nconst timer = React.useRef(null);\n\nuseEffect(() =\u003e {\n  if(timer.current){\n    clearTimeout(timer.current);\n  }\n\n  timer.current = setTimeout(...\n})\n```\n\nbut with a cleanup function you can do\n\n```\nuseEffect(() =\u003e {\n  const timer = setTimeout(...\n\n  return () =\u003e {\n    clearTimeout(timer);\n  }\n})\n```\n\n### Optimize using the dependency array \n\nThere might be a case where you don't want it to run every time but on specific condition for this useEffect (all the hooks) have another parameter known as dependency array, where you can specify the dependent parameter like `[count]`, useEffect will trigger only if `count` changes and cleanup method too.\n\n### Empty dependency array \n\nIs it a special case for `componentWillunmount` and `componentDidMount`? Nope, though it seems like but it is not handled separately.\n\n```\nuseEffect(() =\u003e {\n  ...\n  return () =\u003e {...}\n}, [])\n```\n\n`[]` means no dependency, so useEffect will trigger only during the initial render and cleanup only in unmount phase, React calls all cleanup methods in unmount phase hence it will run, so it behaves same way as `componentWillunmount` and `componentDidMount` but it's not the same.\n\nLast but not least due to closure cleanup will have values of previous state when `useEffect` was executed.\n\nYou can play with `useEffect` [here](https://codesandbox.io/s/understanding-use-effect-hx83v) ","user":{"name":"Mukul Jain","username":"mukuljainx","twitter_username":null,"github_username":"mukuljainx","user_id":217996,"website_url":"http://mukulja.in/","profile_image":"https://media2.dev.to/dynamic/image/width=640,height=640,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F217996%2Fd9f6837e-4bbf-46b4-baab-9ea6a1b228f2.jpeg","profile_image_90":"https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F217996%2Fd9f6837e-4bbf-46b4-baab-9ea6a1b228f2.jpeg"}}