<p dir="auto"><strong>Do you want to request a <em>feature</em> or report a <em>bug</em>?</strong><br>
Reporting a bug.<br>
<strong>What is the current behavior?</strong><br>
Unexpected DOM elements in list rendering<br>
<strong>If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (<a href="https://jsfiddle.net/Luktwrdm/" rel="nofollow">https://jsfiddle.net/Luktwrdm/</a>) or CodeSandbox (<a href="https://codesandbox.io/s/new" rel="nofollow">https://codesandbox.io/s/new</a>) example below:</strong><br>
<a href="https://jsfiddle.net/tse5xcg5/1/" rel="nofollow">https://jsfiddle.net/tse5xcg5/1/</a><br>
just switch the tabs, there are unexpected DOM elements<br>
<strong>What is the expected behavior?</strong><br>
no unexpected DOM elements<br>
<strong>Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?</strong><br>
tested with React &gt;= 16<br>
no extra elements with React 15</p>
<p dir="auto">Duplicate keys are mistakes, but these DOM elements should not be there anyway.</p>
<p dir="auto">Posting this issue to share a common phenomenon related to strict effect, I have created a sandbox to demonstrate this issue: <a href="https://codesandbox.io/s/unmount-guard-in-strict-effect-5eneb?file=/src/App.js" rel="nofollow">https://codesandbox.io/s/unmount-guard-in-strict-effect-5eneb?file=/src/App.js</a></p>
<p dir="auto">Previously this is a common practice to have a <code class="notranslate">unmounted</code> ref indicating whether current component is unmounted, and to prevent calls to <code class="notranslate">setState</code> after unmount in order to get rid of those ugly console warnings.</p>
<p dir="auto">With react 18's strict effect, the intentional "mount -&gt; unmount -&gt; mount" steps may break some unmounted ref implements, the <a href="https://github.com/alibaba/hooks/blob/7b026c03dde61449b051bb63ba68507115227cda/packages/hooks/src/useUnmountedRef/index.ts">ahooks implementation</a> is incorrect while the <a href="https://github.com/streamich/react-use/blob/90e72a5340460816e2159b2c461254661b00e1d3/src/useMountedState.ts">react-use implement</a> is correct.</p>
<p dir="auto">We can simply fix it by "revive" this ref in mount effect:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="const unmounted = useRef(false);
useEffect(
  () =&gt; {
    // Add this line!
    unmounted.current = false;
    return () =&gt; {
      unmounted.current = true;
    };
  },
  []
);"><pre class="notranslate"><code class="notranslate">const unmounted = useRef(false);
useEffect(
  () =&gt; {
    // Add this line!
    unmounted.current = false;
    return () =&gt; {
      unmounted.current = true;
    };
  },
  []
);
</code></pre></div>
<p dir="auto">Still, I have 3 questions related to this:</p>
<ol dir="auto">
<li>In real world concurrent mode, is there a chance that <code class="notranslate">fakeFetch</code> may resolve after component is unmounted and before it is remounted?</li>
<li>Is this mean that we <strong>should not</strong> guard our <code class="notranslate">setState</code> calls with an unmounted ref flag? Maybe simply allow <code class="notranslate">setState</code> on an "unmounted" component can perfectly fix this problem.</li>
<li>Since we don't want to cancel fetch in unmount (maybe this is a side effect, or duplicated request can hit performance), is there any recommended practice to handle such situations?</li>
</ol>