{"componentChunkName":"component---src-templates-blog-js","path":"/blog/2018/06/07/you-probably-dont-need-derived-state.html","result":{"data":{"markdownRemark":{"html":"<p>React 16.4 included a <a href=\"/blog/2018/05/23/react-v-16-4.html#bugfix-for-getderivedstatefromprops\">bugfix for getDerivedStateFromProps</a> which caused some existing bugs in React components to reproduce more consistently. If this release exposed a case where your application was using an anti-pattern and didn’t work properly after the fix, we’re sorry for the churn. In this post, we will explain some common anti-patterns with derived state and our preferred alternatives.</p>\n<p>For a long time, the lifecycle <code class=\"gatsby-code-text\">componentWillReceiveProps</code> was the only way to update state in response to a change in props without an additional render. In version 16.3, <a href=\"/blog/2018/03/29/react-v-16-3.html#component-lifecycle-changes\">we introduced a replacement lifecycle, <code class=\"gatsby-code-text\">getDerivedStateFromProps</code></a> to solve the same use cases in a safer way. At the same time, we’ve realized that people have many misconceptions about how to use both methods, and we’ve found anti-patterns that result in subtle and confusing bugs. The <code class=\"gatsby-code-text\">getDerivedStateFromProps</code> bugfix in 16.4 <a href=\"https://github.com/facebook/react/issues/12898\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">makes derived state more predictable</a>, so the results of misusing it are easier to notice.</p>\n<blockquote>\n<p>Note</p>\n<p>All of the anti-patterns described in this post apply to both the older <code class=\"gatsby-code-text\">componentWillReceiveProps</code> and the newer <code class=\"gatsby-code-text\">getDerivedStateFromProps</code>.</p>\n</blockquote>\n<p> This blog post will cover the following topics:</p>\n<ul>\n<li><a href=\"#when-to-use-derived-state\">When to use derived state</a></li>\n<li>\n<p><a href=\"#common-bugs-when-using-derived-state\">Common bugs when using derived state</a></p>\n<ul>\n<li><a href=\"#anti-pattern-unconditionally-copying-props-to-state\">Anti-pattern: Unconditionally copying props to state</a></li>\n<li><a href=\"#anti-pattern-erasing-state-when-props-change\">Anti-pattern: Erasing state when props change</a></li>\n</ul>\n</li>\n<li><a href=\"#preferred-solutions\">Preferred solutions</a></li>\n<li><a href=\"#what-about-memoization\">What about memoization?</a></li>\n</ul>\n<h2 id=\"when-to-use-derived-state\"><a href=\"#when-to-use-derived-state\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>When to Use Derived State </h2>\n<p><code class=\"gatsby-code-text\">getDerivedStateFromProps</code> exists for only one purpose. It enables a component to update its internal state as the result of <strong>changes in props</strong>. Our previous blog post provided some examples, like <a href=\"/blog/2018/03/27/update-on-async-rendering.html#updating-state-based-on-props\">recording the current scroll direction based on a changing offset prop</a> or <a href=\"/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data-when-props-change\">loading external data specified by a source prop</a>.</p>\n<p>We did not provide many examples, because as a general rule, <strong>derived state should be used sparingly</strong>. All problems with derived state that we have seen can be ultimately reduced to either (1) unconditionally updating state from props or (2) updating state whenever props and state don’t match. (We’ll go over both in more detail below.)</p>\n<ul>\n<li>If you’re using derived state to memoize some computation based only on the current props, you don’t need derived state. See <a href=\"#what-about-memoization\">What about memoization?</a> below.</li>\n<li>If you’re updating derived state unconditionally or updating it whenever props and state don’t match, your component likely resets its state too frequently. Read on for more details.</li>\n</ul>\n<h2 id=\"common-bugs-when-using-derived-state\"><a href=\"#common-bugs-when-using-derived-state\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Common Bugs When Using Derived State </h2>\n<p>The terms <a href=\"/docs/forms.html#controlled-components\">“controlled”</a> and <a href=\"/docs/uncontrolled-components.html\">“uncontrolled”</a> usually refer to form inputs, but they can also describe where any component’s data lives. Data passed in as props can be thought of as <strong>controlled</strong> (because the parent component <em>controls</em> that data). Data that exists only in internal state can be thought of as <strong>uncontrolled</strong> (because the parent can’t directly change it).</p>\n<p>The most common mistake with derived state is mixing these two; when a derived state value is also updated by <code class=\"gatsby-code-text\">setState</code> calls, there isn’t a single source of truth for the data. The <a href=\"/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data-when-props-change\">external data loading example</a> mentioned above may sound similar, but it’s different in a few important ways. In the loading example, there is a clear source of truth for both the “source” prop and the “loading” state. When the source prop changes, the loading state should <strong>always</strong> be overridden. Conversely, the state is overridden only when the prop <strong>changes</strong> and is otherwise managed by the component.</p>\n<p>Problems arise when any of these constraints are changed. This typically comes in two forms. Let’s take a look at both.</p>\n<h3 id=\"anti-pattern-unconditionally-copying-props-to-state\"><a href=\"#anti-pattern-unconditionally-copying-props-to-state\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Anti-pattern: Unconditionally copying props to state </h3>\n<p>A common misconception is that <code class=\"gatsby-code-text\">getDerivedStateFromProps</code> and <code class=\"gatsby-code-text\">componentWillReceiveProps</code> are only called when props “change”. These lifecycles are called any time a parent component rerenders, regardless of whether the props are “different” from before. Because of this, it has always been unsafe to <em>unconditionally</em> override state using either of these lifecycles. <strong>Doing so will cause state updates to be lost.</strong></p>\n<p>Let’s consider an example to demonstrate the problem. Here is an <code class=\"gatsby-code-text\">EmailInput</code> component that “mirrors” an email prop in state:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">EmailInput</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Component</span> <span class=\"token punctuation\">{</span>\n  state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> email<span class=\"token operator\">:</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>email <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\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 keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">onChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleChange<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>email<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function-variable function\">handleChange</span> <span class=\"token operator\">=</span> <span class=\"token parameter\">event</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</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> email<span class=\"token operator\">:</span> event<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value <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\n  <span class=\"token function\">componentWillReceiveProps</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">nextProps</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// This will erase any local state updates!</span>\n    <span class=\"token comment\">// Do not do this.</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> email<span class=\"token operator\">:</span> nextProps<span class=\"token punctuation\">.</span>email <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>At first, this component might look okay. State is initialized to the value specified by props and updated when we type into the <code class=\"gatsby-code-text\">&lt;input&gt;</code>. But if our component’s parent rerenders, anything we’ve typed into the <code class=\"gatsby-code-text\">&lt;input&gt;</code> will be lost! (<a href=\"https://codesandbox.io/s/m3w9zn1z8x\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">See this demo for an example.</a>) This holds true even if we were to compare <code class=\"gatsby-code-text\">nextProps.email !== this.state.email</code> before resetting.</p>\n<p>In this simple example, adding <code class=\"gatsby-code-text\">shouldComponentUpdate</code> to rerender only when the email prop has changed could fix this. However in practice, components usually accept multiple props; another prop changing would still cause a rerender and improper reset. Function and object props are also often created inline, making it hard to implement a <code class=\"gatsby-code-text\">shouldComponentUpdate</code> that reliably returns true only when a material change has happened. <a href=\"https://codesandbox.io/s/jl0w6r9w59\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Here is a demo that shows that happening.</a> As a result, <code class=\"gatsby-code-text\">shouldComponentUpdate</code> is best used as a performance optimization, not to ensure correctness of derived state.</p>\n<p>Hopefully it’s clear by now why <strong>it is a bad idea to unconditionally copy props to state</strong>. Before reviewing possible solutions, let’s look at a related problematic pattern: what if we were to only update the state when the email prop changes?</p>\n<h3 id=\"anti-pattern-erasing-state-when-props-change\"><a href=\"#anti-pattern-erasing-state-when-props-change\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Anti-pattern: Erasing state when props change </h3>\n<p>Continuing the example above, we could avoid accidentally erasing state by only updating it when <code class=\"gatsby-code-text\">props.email</code> changes:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">EmailInput</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Component</span> <span class=\"token punctuation\">{</span>\n  state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    email<span class=\"token operator\">:</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>email\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">componentWillReceiveProps</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">nextProps</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Any time props.email changes, update state.</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>nextProps<span class=\"token punctuation\">.</span>email <span class=\"token operator\">!==</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>email<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</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>\n        email<span class=\"token operator\">:</span> nextProps<span class=\"token punctuation\">.</span>email\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span>\n  \n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<blockquote>\n<p>Note</p>\n<p>Even though the example above shows <code class=\"gatsby-code-text\">componentWillReceiveProps</code>, the same anti-pattern applies to <code class=\"gatsby-code-text\">getDerivedStateFromProps</code>.</p>\n</blockquote>\n<p>We’ve just made a big improvement. Now our component will erase what we’ve typed only when the props actually change.</p>\n<p>There is still a subtle problem. Imagine a password manager app using the above input component. When navigating between details for two accounts with the same email, the input would fail to reset. This is because the prop value passed to the component would be the same for both accounts! This would be a surprise to the user, as an unsaved change to one account would appear to affect other accounts that happened to share the same email. (<a href=\"https://codesandbox.io/s/mz2lnkjkrx\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">See demo here.</a>)</p>\n<p>This design is fundamentally flawed, but it’s also an easy mistake to make. (<a href=\"https://twitter.com/brian_d_vaughn/status/959600888242307072\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">I’ve made it myself!</a>) Fortunately there are two alternatives that work better. The key to both is that <strong>for any piece of data, you need to pick a single component that owns it as the source of truth, and avoid duplicating it in other components.</strong> Let’s take a look at each of the alternatives.</p>\n<h2 id=\"preferred-solutions\"><a href=\"#preferred-solutions\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Preferred Solutions </h2>\n<h3 id=\"recommendation-fully-controlled-component\"><a href=\"#recommendation-fully-controlled-component\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Recommendation: Fully controlled component </h3>\n<p>One way to avoid the problems mentioned above is to remove state from our component entirely. If the email address only exists as a prop, then we don’t have to worry about conflicts with state. We could even convert <code class=\"gatsby-code-text\">EmailInput</code> to a lighter-weight function component:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">function</span> <span class=\"token function\">EmailInput</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">onChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>props<span class=\"token punctuation\">.</span>onChange<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>props<span class=\"token punctuation\">.</span>email<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>This approach simplifies the implementation of our component, but if we still want to store a draft value, the parent form component will now need to do that manually. (<a href=\"https://codesandbox.io/s/7154w1l551\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Click here to see a demo of this pattern.</a>)</p>\n<h3 id=\"recommendation-fully-uncontrolled-component-with-a-key\"><a href=\"#recommendation-fully-uncontrolled-component-with-a-key\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Recommendation: Fully uncontrolled component with a <code class=\"gatsby-code-text\">key</code> </h3>\n<p>Another alternative would be for our component to fully own the “draft” email state. In that case, our component could still accept a prop for the <em>initial</em> value, but it would ignore subsequent changes to that prop:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">EmailInput</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Component</span> <span class=\"token punctuation\">{</span>\n  state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> email<span class=\"token operator\">:</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>defaultEmail <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function-variable function\">handleChange</span> <span class=\"token operator\">=</span> <span class=\"token parameter\">event</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</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> email<span class=\"token operator\">:</span> event<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value <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\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 keyword\">return</span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">onChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleChange<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>email<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>In order to reset the value when moving to a different item (as in our password manager scenario), we can use the special React attribute called <code class=\"gatsby-code-text\">key</code>. When a <code class=\"gatsby-code-text\">key</code> changes, React will <a href=\"/docs/reconciliation.html#keys\"><em>create</em> a new component instance rather than <em>update</em> the current one</a>. Keys are usually used for dynamic lists but are also useful here. In our case, we could use the user ID to recreate the email input any time a new user is selected:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">EmailInput</span></span>\n  <span class=\"token attr-name\">defaultEmail</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>user<span class=\"token punctuation\">.</span>email<span class=\"token punctuation\">}</span></span>\n  <span class=\"token attr-name\">key</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>user<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">}</span></span>\n<span class=\"token punctuation\">/></span></span></code></pre></div>\n<p>Each time the ID changes, the <code class=\"gatsby-code-text\">EmailInput</code> will be recreated and its state will be reset to the latest <code class=\"gatsby-code-text\">defaultEmail</code> value. (<a href=\"https://codesandbox.io/s/6v1znlxyxn\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Click here to see a demo of this pattern.</a>) With this approach, you don’t have to add <code class=\"gatsby-code-text\">key</code> to every input. It might make more sense to put a <code class=\"gatsby-code-text\">key</code> on the whole form instead. Every time the key changes, all components within the form will be recreated with a freshly initialized state.</p>\n<p>In most cases, this is the best way to handle state that needs to be reset.</p>\n<blockquote>\n<p>Note</p>\n<p>While this may sound slow, the performance difference is usually insignificant. Using a key can even be faster if the components have heavy logic that runs on updates since diffing gets bypassed for that subtree.</p>\n</blockquote>\n<h4 id=\"alternative-1-reset-uncontrolled-component-with-an-id-prop\"><a href=\"#alternative-1-reset-uncontrolled-component-with-an-id-prop\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Alternative 1: Reset uncontrolled component with an ID prop </h4>\n<p>If <code class=\"gatsby-code-text\">key</code> doesn’t work for some reason (perhaps the component is very expensive to initialize), a workable but cumbersome solution would be to watch for changes to “userID” in <code class=\"gatsby-code-text\">getDerivedStateFromProps</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">EmailInput</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Component</span> <span class=\"token punctuation\">{</span>\n  state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    email<span class=\"token operator\">:</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>defaultEmail<span class=\"token punctuation\">,</span>\n    prevPropsUserID<span class=\"token operator\">:</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>userID\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token keyword\">static</span> <span class=\"token function\">getDerivedStateFromProps</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props<span class=\"token punctuation\">,</span> state</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Any time the current user changes,</span>\n    <span class=\"token comment\">// Reset any parts of state that are tied to that user.</span>\n    <span class=\"token comment\">// In this simple example, that's just the email.</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>props<span class=\"token punctuation\">.</span>userID <span class=\"token operator\">!==</span> state<span class=\"token punctuation\">.</span>prevPropsUserID<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span>\n        prevPropsUserID<span class=\"token operator\">:</span> props<span class=\"token punctuation\">.</span>userID<span class=\"token punctuation\">,</span>\n        email<span class=\"token operator\">:</span> props<span class=\"token punctuation\">.</span>defaultEmail\n      <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>This also provides the flexibility to only reset parts of our component’s internal state if we so choose. (<a href=\"https://codesandbox.io/s/rjyvp7l3rq\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Click here to see a demo of this pattern.</a>)</p>\n<blockquote>\n<p>Note</p>\n<p>Even though the example above shows <code class=\"gatsby-code-text\">getDerivedStateFromProps</code>, the same technique can be used with <code class=\"gatsby-code-text\">componentWillReceiveProps</code>.</p>\n</blockquote>\n<h4 id=\"alternative-2-reset-uncontrolled-component-with-an-instance-method\"><a href=\"#alternative-2-reset-uncontrolled-component-with-an-instance-method\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Alternative 2: Reset uncontrolled component with an instance method </h4>\n<p>More rarely, you may need to reset state even if there’s no appropriate ID to use as <code class=\"gatsby-code-text\">key</code>. One solution is to reset the key to a random value or autoincrementing number each time you want to reset. One other viable alternative is to expose an instance method to imperatively reset the internal state:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">EmailInput</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Component</span> <span class=\"token punctuation\">{</span>\n  state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    email<span class=\"token operator\">:</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>defaultEmail\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function\">resetEmailForNewUser</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">newEmail</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</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> email<span class=\"token operator\">:</span> newEmail <span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token comment\">// ...</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The parent form component could then <a href=\"/docs/glossary.html#refs\">use a <code class=\"gatsby-code-text\">ref</code> to call this method</a>. (<a href=\"https://codesandbox.io/s/l70krvpykl\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Click here to see a demo of this pattern.</a>)</p>\n<p>Refs can be useful in certain cases like this one, but generally we recommend you use them sparingly. Even in the demo, this imperative method is nonideal because two renders will occur instead of one.</p>\n<hr>\n<h3 id=\"recap\"><a href=\"#recap\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Recap </h3>\n<p>To recap, when designing a component, it is important to decide whether its data will be controlled or uncontrolled.</p>\n<p>Instead of trying to <strong>“mirror” a prop value in state</strong>, make the component <strong>controlled</strong>, and consolidate the two diverging values in the state of some parent component. For example, rather than a child accepting a “committed” <code class=\"gatsby-code-text\">props.value</code> and tracking a “draft” <code class=\"gatsby-code-text\">state.value</code>, have the parent manage both <code class=\"gatsby-code-text\">state.draftValue</code> and <code class=\"gatsby-code-text\">state.committedValue</code> and control the child’s value directly. This makes the data flow more explicit and predictable.</p>\n<p>For <strong>uncontrolled</strong> components, if you’re trying to reset state when a particular prop (usually an ID) changes, you have a few options:</p>\n<ul>\n<li><strong>Recommendation: To reset <em>all internal state</em>, use the <code class=\"gatsby-code-text\">key</code> attribute.</strong></li>\n<li>Alternative 1: To reset <em>only certain state fields</em>, watch for changes in a special property (e.g. <code class=\"gatsby-code-text\">props.userID</code>).</li>\n<li>Alternative 2: You can also consider fall back to an imperative instance method using refs.</li>\n</ul>\n<h2 id=\"what-about-memoization\"><a href=\"#what-about-memoization\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What about memoization? </h2>\n<p>We’ve also seen derived state used to ensure an expensive value used in <code class=\"gatsby-code-text\">render</code> is recomputed only when the inputs change. This technique is known as <a href=\"https://en.wikipedia.org/wiki/Memoization\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">memoization</a>.</p>\n<p>Using derived state for memoization isn’t necessarily bad, but it’s usually not the best solution. There is inherent complexity in managing derived state, and this complexity increases with each additional property. For example, if we add a second derived field to our component state then our implementation would need to separately track changes to both.</p>\n<p>Let’s look at an example of one component that takes one prop—a list of items—and renders the items that match a search query entered by the user. We could use derived state to store the filtered list:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">Example</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Component</span> <span class=\"token punctuation\">{</span>\n  state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    filterText<span class=\"token operator\">:</span> <span class=\"token string\">\"\"</span><span class=\"token punctuation\">,</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// *******************************************************</span>\n  <span class=\"token comment\">// NOTE: this example is NOT the recommended approach.</span>\n  <span class=\"token comment\">// See the examples below for our recommendations instead.</span>\n  <span class=\"token comment\">// *******************************************************</span>\n\n  <span class=\"token keyword\">static</span> <span class=\"token function\">getDerivedStateFromProps</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">props<span class=\"token punctuation\">,</span> state</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// Re-run the filter whenever the list array or filter text change.</span>\n    <span class=\"token comment\">// Note we need to store prevPropsList and prevFilterText to detect changes.</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>\n      props<span class=\"token punctuation\">.</span>list <span class=\"token operator\">!==</span> state<span class=\"token punctuation\">.</span>prevPropsList <span class=\"token operator\">||</span>\n      state<span class=\"token punctuation\">.</span>prevFilterText <span class=\"token operator\">!==</span> state<span class=\"token punctuation\">.</span>filterText\n    <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span>\n        prevPropsList<span class=\"token operator\">:</span> props<span class=\"token punctuation\">.</span>list<span class=\"token punctuation\">,</span>\n        prevFilterText<span class=\"token operator\">:</span> state<span class=\"token punctuation\">.</span>filterText<span class=\"token punctuation\">,</span>\n        filteredList<span class=\"token operator\">:</span> props<span class=\"token punctuation\">.</span>list<span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">item</span> <span class=\"token operator\">=></span> item<span class=\"token punctuation\">.</span>text<span class=\"token punctuation\">.</span><span class=\"token function\">includes</span><span class=\"token punctuation\">(</span>state<span class=\"token punctuation\">.</span>filterText<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>\n    <span class=\"token keyword\">return</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token function-variable function\">handleChange</span> <span class=\"token operator\">=</span> <span class=\"token parameter\">event</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</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> filterText<span class=\"token operator\">:</span> event<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value <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\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 keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Fragment</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">onChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleChange<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>filterText<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>ul</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>filteredList<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">item</span> <span class=\"token operator\">=></span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>li</span> <span class=\"token attr-name\">key</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>item<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>item<span class=\"token punctuation\">.</span>text<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>li</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>ul</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span><span class=\"token class-name\">Fragment</span></span><span class=\"token punctuation\">></span></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>This implementation avoids recalculating <code class=\"gatsby-code-text\">filteredList</code> more often than necessary. But it is more complicated than it needs to be, because it has to separately track and detect changes in both props and state in order to properly update the filtered list. In this example, we could simplify things by using <code class=\"gatsby-code-text\">PureComponent</code> and moving the filter operation into the render method: </p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token comment\">// PureComponents only rerender if at least one state or prop value changes.</span>\n<span class=\"token comment\">// Change is determined by doing a shallow comparison of state and prop keys.</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">Example</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">PureComponent</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// State only needs to hold the current filter text value:</span>\n  state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    filterText<span class=\"token operator\">:</span> <span class=\"token string\">\"\"</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function-variable function\">handleChange</span> <span class=\"token operator\">=</span> <span class=\"token parameter\">event</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</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> filterText<span class=\"token operator\">:</span> event<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value <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\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 comment\">// The render method on this PureComponent is called only if</span>\n    <span class=\"token comment\">// props.list or state.filterText has changed.</span>\n    <span class=\"token keyword\">const</span> filteredList <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>list<span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span>\n      <span class=\"token parameter\">item</span> <span class=\"token operator\">=></span> item<span class=\"token punctuation\">.</span>text<span class=\"token punctuation\">.</span><span class=\"token function\">includes</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>filterText<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Fragment</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">onChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleChange<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>filterText<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>ul</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>filteredList<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">item</span> <span class=\"token operator\">=></span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>li</span> <span class=\"token attr-name\">key</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>item<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>item<span class=\"token punctuation\">.</span>text<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>li</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>ul</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span><span class=\"token class-name\">Fragment</span></span><span class=\"token punctuation\">></span></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>The above approach is much cleaner and simpler than the derived state version. Occasionally, this won’t be good enough—filtering may be slow for large lists, and <code class=\"gatsby-code-text\">PureComponent</code> won’t prevent rerenders if another prop were to change. To address both of these concerns, we could add a memoization helper to avoid unnecessarily re-filtering our list:</p>\n<div class=\"gatsby-highlight\" data-language=\"jsx\"><pre class=\"gatsby-code-jsx\"><code class=\"gatsby-code-jsx\"><span class=\"token keyword\">import</span> memoize <span class=\"token keyword\">from</span> <span class=\"token string\">\"memoize-one\"</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">Example</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">Component</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token comment\">// State only needs to hold the current filter text value:</span>\n  state <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> filterText<span class=\"token operator\">:</span> <span class=\"token string\">\"\"</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token comment\">// Re-run the filter whenever the list array or filter text changes:</span>\n  filter <span class=\"token operator\">=</span> <span class=\"token function\">memoize</span><span class=\"token punctuation\">(</span>\n    <span class=\"token punctuation\">(</span><span class=\"token parameter\">list<span class=\"token punctuation\">,</span> filterText</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=></span> list<span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">item</span> <span class=\"token operator\">=></span> item<span class=\"token punctuation\">.</span>text<span class=\"token punctuation\">.</span><span class=\"token function\">includes</span><span class=\"token punctuation\">(</span>filterText<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n  <span class=\"token function-variable function\">handleChange</span> <span class=\"token operator\">=</span> <span class=\"token parameter\">event</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">{</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> filterText<span class=\"token operator\">:</span> event<span class=\"token punctuation\">.</span>target<span class=\"token punctuation\">.</span>value <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\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 comment\">// Calculate the latest filtered list. If these arguments haven't changed</span>\n    <span class=\"token comment\">// since the last render, `memoize-one` will reuse the last return value.</span>\n    <span class=\"token keyword\">const</span> filteredList <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span><span class=\"token function\">filter</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>props<span class=\"token punctuation\">.</span>list<span class=\"token punctuation\">,</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>filterText<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span><span class=\"token class-name\">Fragment</span></span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>input</span> <span class=\"token attr-name\">onChange</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>handleChange<span class=\"token punctuation\">}</span></span> <span class=\"token attr-name\">value</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>state<span class=\"token punctuation\">.</span>filterText<span class=\"token punctuation\">}</span></span> <span class=\"token punctuation\">/></span></span><span class=\"token plain-text\">\n        </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>ul</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>filteredList<span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">item</span> <span class=\"token operator\">=></span> <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>li</span> <span class=\"token attr-name\">key</span><span class=\"token script language-javascript\"><span class=\"token script-punctuation punctuation\">=</span><span class=\"token punctuation\">{</span>item<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">}</span></span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">{</span>item<span class=\"token punctuation\">.</span>text<span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>li</span><span class=\"token punctuation\">></span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">}</span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>ul</span><span class=\"token punctuation\">></span></span><span class=\"token plain-text\">\n      </span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span><span class=\"token class-name\">Fragment</span></span><span class=\"token punctuation\">></span></span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>This is much simpler and performs just as well as the derived state version!</p>\n<p>When using memoization, remember a couple of constraints:</p>\n<ol>\n<li>In most cases, you’ll want to <strong>attach the memoized function to a component instance</strong>. This prevents multiple instances of a component from resetting each other’s memoized keys.</li>\n<li>Typically you’ll want to use a memoization helper with a <strong>limited cache size</strong> in order to prevent memory leaks over time. (In the example above, we used <code class=\"gatsby-code-text\">memoize-one</code> because it only caches the most recent arguments and result.)</li>\n<li>None of the implementations shown in this section will work if <code class=\"gatsby-code-text\">props.list</code> is recreated each time the parent component renders. But in most cases, this setup is appropriate.</li>\n</ol>\n<h2 id=\"in-closing\"><a href=\"#in-closing\" aria-hidden class=\"anchor\"><svg aria-hidden=\"true\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>In closing </h2>\n<p>In real world applications, components often contain a mix of controlled and uncontrolled behaviors. This is okay! If each value has a clear source of truth, you can avoid the anti-patterns mentioned above.</p>\n<p>It is also worth re-iterating that <code class=\"gatsby-code-text\">getDerivedStateFromProps</code> (and derived state in general) is an advanced feature and should be used sparingly because of this complexity. If your use case falls outside of these patterns, please share it with us on <a href=\"https://github.com/reactjs/reactjs.org/issues/new\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">GitHub</a> or <a href=\"https://twitter.com/reactjs\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Twitter</a>!</p>","excerpt":"React 16.4 included a bugfix for getDerivedStateFromProps which caused some existing bugs in React components to reproduce more consistently. If this release exposed a case where your application was using an anti-pattern and didn’t work properly after the fix, we’re sorry for the churn. In this post, we will explain some common anti-patterns with derived state and our preferred alternatives. For a long time, the lifecycle  was the only way to update state in response to a change in props…","frontmatter":{"title":"You Probably Don't Need Derived State","next":null,"prev":null,"author":[{"frontmatter":{"name":"Brian Vaughn","url":"https://github.com/bvaughn"}}]},"fields":{"date":"June 07, 2018","path":"content/blog/2018-06-07-you-probably-dont-need-derived-state.md","slug":"/blog/2018/06/07/you-probably-dont-need-derived-state.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/2018/06/07/you-probably-dont-need-derived-state.html"}},"staticQueryHashes":[]}