<p dir="auto">It's currently difficult (impossible?) to create plugins for React that use any of the stuff in <code class="notranslate">lib</code> without using <a href="https://github.com/andreypopp/react-router-component-bower/blob/master/package.json">crazy hacks</a>.</p>
<p dir="auto">What's the best way to do this? Separate modules?</p>
<p dir="auto"><strong>Do you want to request a <em>feature</em> or report a <em>bug</em>?</strong></p>
<p dir="auto">Feature</p>
<hr>
<p dir="auto">There's a common case of having a list of items, keyed by some id, and items can be added/removed over time. For example, say we have a list of users and a button to refresh the list with new data from the server. Here, <code class="notranslate">User</code> is a simple function component.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="users.map((user) =&gt; (
  &lt;User key={user.id} data={user} /&gt;
)"><pre class="notranslate"><span class="pl-s1">users</span><span class="pl-kos">.</span><span class="pl-c1">map</span><span class="pl-kos">(</span><span class="pl-kos">(</span><span class="pl-s1">user</span><span class="pl-kos">)</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span>
  <span class="pl-c1">&lt;</span><span class="pl-ent">User</span> <span class="pl-c1">key</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-s1">user</span><span class="pl-kos">.</span><span class="pl-c1">id</span><span class="pl-kos">}</span> <span class="pl-c1">data</span><span class="pl-c1">=</span><span class="pl-kos">{</span><span class="pl-s1">user</span><span class="pl-kos">}</span> <span class="pl-c1">/</span><span class="pl-c1">&gt;</span>
<span class="pl-kos">)</span></pre></div>
<p dir="auto">Say this produces the following User elements:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="key: 1000, data: { name: 'foo' }
key: 1001, data: { name: 'bar' }
key: 1002, data: { name: 'baz' }"><pre class="notranslate"><code class="notranslate">key: 1000, data: { name: 'foo' }
key: 1001, data: { name: 'bar' }
key: 1002, data: { name: 'baz' }
</code></pre></div>
<p dir="auto">Later we get the new user list, and these are the resulting elements:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="key: 1003, data: { name: 'quux' }
key: 1002, data: { name: 'baz' }
key: 1001, data: { name: 'bar' }"><pre class="notranslate"><code class="notranslate">key: 1003, data: { name: 'quux' }
key: 1002, data: { name: 'baz' }
key: 1001, data: { name: 'bar' }
</code></pre></div>
<p dir="auto">The operations are:</p>
<ul dir="auto">
<li>remove 1000, destroy instance and dom nodes</li>
<li>move 1002, update</li>
<li>create 1003, with instance and dom nodes</li>
</ul>
<p dir="auto">Would an option to tell React that it can reuse the instances and dom nodes make sense?</p>
<p dir="auto">From the list diff, React has this information (as I understand it):</p>
<ul dir="auto">
<li>remove at key: 1000, type: User, index: 0</li>
<li>create at key: 1003, type: User. index: 0</li>
</ul>
<p dir="auto">If we signaled to React that it can reuse elements, and since the 'type' is the same, it could reduce these operations to updating the identity of the underlying instance (key: 1000 -&gt; key: 1003) and then update the instance normally. It could also require a move, but it doesn't here.</p>
<p dir="auto">When used, it reduces the combined create/destroy operations of instances and dom nodes from <code class="notranslate">create + destroy</code> to <code class="notranslate">Math.abs(create - destroy)</code>.</p>
<p dir="auto">Of course, this has to be opt-in behavior because some components won't clear their internal state, and some DOM nodes can hold uncontrolled state. Also in some cases this could be slower (but I'd wager this is rare).</p>
<p dir="auto">The syntax is secondary; I mostly want to hear what's thought about the idea of explicitly permitting React to reuse instances, but this is the simplest idea I have.</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;React.Reusable&gt;
  {users.map(...)}
&lt;/React.Reusable&gt;"><pre class="notranslate"><span class="pl-c1">&lt;</span><span class="pl-v">React</span><span class="pl-kos">.</span><span class="pl-v">Reusable</span><span class="pl-c1">&gt;</span>
  <span class="pl-kos">{</span><span class="pl-s1">users</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span>...<span class="pl-kos">)</span><span class="pl-kos">}</span>
<span class="pl-c1">&lt;</span><span class="pl-c1">/</span><span class="pl-v">React</span><span class="pl-kos">.</span><span class="pl-v">Reusable</span><span class="pl-c1">&gt;</span></pre></div>
<hr>
<p dir="auto"><strong>Why do this in core?</strong></p>
<p dir="auto">I can't think of a reasonable way to do this in user space, and the less reasonable ways require duplicating the effort of diffing the list.</p>
<p dir="auto">It's just allowing React to simplify the operations it intends to perform.</p>
<p dir="auto"><strong>Why do this at all?</strong></p>
<p dir="auto">It provides another performance hook for React code, which people can attempt to apply while optimizing their react and react-native apps, if it makes sense in their situation.</p>