{"componentChunkName":"component---src-templates-blog-js","path":"/blog/2015/12/16/ismounted-antipattern.html","result":{"data":{"markdownRemark":{"html":"<p>As we move closer to officially deprecating isMounted, it’s worth understanding why the function is an antipattern, and how to write code without the isMounted function.</p>\n<p>The primary use case for <code class=\"gatsby-code-text\">isMounted()</code> is to avoid calling <code class=\"gatsby-code-text\">setState()</code> after a component has unmounted, because calling <code class=\"gatsby-code-text\">setState()</code> after a component has unmounted will emit a warning. The “setState warning” exists to help you catch bugs, because calling <code class=\"gatsby-code-text\">setState()</code> on an unmounted component is an indication that your app/component has somehow failed to clean up properly. Specifically, calling <code class=\"gatsby-code-text\">setState()</code> in an unmounted component means that your app is still holding a reference to the component after the component has been unmounted - which often indicates a memory leak!</p>\n<p>To avoid the error message, people often add lines like this:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">isMounted</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> <span class=\"token comment\">// This is bad.</span>\n  <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span><span class=\"token operator\">...</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Checking <code class=\"gatsby-code-text\">isMounted</code> before calling <code class=\"gatsby-code-text\">setState()</code> does eliminate the warning, but it also defeats the purpose of the warning, since now you will never get the warning (even when you should!)</p>\n<p>Other uses of <code class=\"gatsby-code-text\">isMounted()</code> are similarly erroneous; using <code class=\"gatsby-code-text\">isMounted()</code> is a code smell because the only reason you would check is because you think you might be holding a reference after the component has unmounted.</p>\n<p>An easy migration strategy for anyone upgrading their code to avoid <code class=\"gatsby-code-text\">isMounted()</code> is to track the mounted status yourself.  Just set a <code class=\"gatsby-code-text\">_isMounted</code> property to true in <code class=\"gatsby-code-text\">componentDidMount</code> and set it to false in <code class=\"gatsby-code-text\">componentWillUnmount</code>, and use this variable to check your component’s status.</p>\n<p>An optimal solution would be to find places where <code class=\"gatsby-code-text\">setState()</code> might be called after a component has unmounted, and fix them. Such situations most commonly occur due to callbacks, when a component is waiting for some data and gets unmounted before the data arrives. Ideally, any callbacks should be canceled in <code class=\"gatsby-code-text\">componentWillUnmount</code>, prior to unmounting.</p>\n<p>For instance, if you are using a Flux store in your component, you must unsubscribe in <code class=\"gatsby-code-text\">componentWillUnmount</code>:</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">MyComponent</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">React<span class=\"token punctuation\">.</span>Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">componentDidMount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    mydatastore<span class=\"token punctuation\">.</span><span class=\"token function\">subscribe</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token function\">render</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token operator\">...</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token function\">componentWillUnmount</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">    mydatastore<span class=\"token punctuation\">.</span><span class=\"token function\">unsubscribe</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span>  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>If you use ES6 promises, you may need to wrap your promise in order to make it cancelable.</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">const</span> cancelablePromise <span class=\"token operator\">=</span> <span class=\"token function\">makeCancelable</span><span class=\"token punctuation\">(</span>\n  <span class=\"token keyword\">new</span> <span class=\"token class-name\">Promise</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">r</span> <span class=\"token operator\">=></span> component<span class=\"token punctuation\">.</span><span class=\"token function\">setState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span><span class=\"token operator\">...</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\ncancelablePromise\n  <span class=\"token punctuation\">.</span>promise\n  <span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'resolved'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">.</span><span class=\"token function\">catch</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">reason</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> console<span class=\"token punctuation\">.</span><span class=\"token function\">log</span><span class=\"token punctuation\">(</span><span class=\"token string\">'isCanceled'</span><span class=\"token punctuation\">,</span> reason<span class=\"token punctuation\">.</span>isCanceled<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\ncancelablePromise<span class=\"token punctuation\">.</span><span class=\"token function\">cancel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token comment\">// Cancel the promise</span></code></pre></div>\n<p>Where <code class=\"gatsby-code-text\">makeCancelable</code> was originally <a href=\"https://github.com/facebook/react/issues/5465#issuecomment-157888325\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">defined by @istarkov</a> as:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">const</span> <span class=\"token function-variable function\">makeCancelable</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token parameter\">promise</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">let</span> hasCanceled_ <span class=\"token operator\">=</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">const</span> wrappedPromise <span class=\"token operator\">=</span> <span class=\"token keyword\">new</span> <span class=\"token class-name\">Promise</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">resolve<span class=\"token punctuation\">,</span> reject</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</span>\n    promise<span class=\"token punctuation\">.</span><span class=\"token function\">then</span><span class=\"token punctuation\">(</span>\n      <span class=\"token parameter\">val</span> <span class=\"token operator\">=></span> hasCanceled_ <span class=\"token operator\">?</span> <span class=\"token function\">reject</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>isCanceled<span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token function\">resolve</span><span class=\"token punctuation\">(</span>val<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n      <span class=\"token parameter\">error</span> <span class=\"token operator\">=></span> hasCanceled_ <span class=\"token operator\">?</span> <span class=\"token function\">reject</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">{</span>isCanceled<span class=\"token operator\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token function\">reject</span><span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span>\n    promise<span class=\"token operator\">:</span> wrappedPromise<span class=\"token punctuation\">,</span>\n    <span class=\"token function\">cancel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      hasCanceled_ <span class=\"token operator\">=</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>As an added bonus for getting your code cleaned up early, getting rid of <code class=\"gatsby-code-text\">isMounted()</code> makes it one step easier for you to upgrade to ES6 classes, where using <code class=\"gatsby-code-text\">isMounted()</code> is already prohibited.  Happy coding!</p>","excerpt":"As we move closer to officially deprecating isMounted, it’s worth understanding why the function is an antipattern, and how to write code without the isMounted function. The primary use case for  is to avoid calling  after a component has unmounted, because calling  after a component has unmounted will emit a warning. The “setState warning” exists to help you catch bugs, because calling  on an unmounted component is an indication that your app/component has somehow failed to clean up properly…","frontmatter":{"title":"isMounted is an Antipattern","next":null,"prev":null,"author":[{"frontmatter":{"name":"Jim Sproch","url":"http://www.jimsproch.com"}}]},"fields":{"date":"December 16, 2015","path":"content/blog/2015-12-16-ismounted-antipattern.md","slug":"/blog/2015/12/16/ismounted-antipattern.html"}},"allMarkdownRemark":{"edges":[{"node":{"frontmatter":{"title":"Introducing the New JSX Transform"},"fields":{"slug":"/blog/2020/09/22/introducing-the-new-jsx-transform.html"}}},{"node":{"frontmatter":{"title":"React v17.0 Release Candidate: No New Features"},"fields":{"slug":"/blog/2020/08/10/react-v17-rc.html"}}},{"node":{"frontmatter":{"title":"React v16.13.0"},"fields":{"slug":"/blog/2020/02/26/react-v16.13.0.html"}}},{"node":{"frontmatter":{"title":"Building Great User Experiences with Concurrent Mode and Suspense"},"fields":{"slug":"/blog/2019/11/06/building-great-user-experiences-with-concurrent-mode-and-suspense.html"}}},{"node":{"frontmatter":{"title":"Preparing for the Future with React Prereleases"},"fields":{"slug":"/blog/2019/10/22/react-release-channels.html"}}},{"node":{"frontmatter":{"title":"Introducing the New React DevTools"},"fields":{"slug":"/blog/2019/08/15/new-react-devtools.html"}}},{"node":{"frontmatter":{"title":"React v16.9.0 and the Roadmap Update"},"fields":{"slug":"/blog/2019/08/08/react-v16.9.0.html"}}},{"node":{"frontmatter":{"title":"Is React Translated Yet? ¡Sí! Sim! はい！"},"fields":{"slug":"/blog/2019/02/23/is-react-translated-yet.html"}}},{"node":{"frontmatter":{"title":"React v16.8: The One With Hooks"},"fields":{"slug":"/blog/2019/02/06/react-v16.8.0.html"}}},{"node":{"frontmatter":{"title":"React v16.7: No, This Is Not the One With Hooks"},"fields":{"slug":"/blog/2018/12/19/react-v-16-7.html"}}}]}},"pageContext":{"slug":"/blog/2015/12/16/ismounted-antipattern.html"}},"staticQueryHashes":[]}