title: Remove React components that throw an error from a grid
body: <p>I have a React component that displays a grid of tiles. Some of those tiles might throw an error when they try to render. Using an error boundary I could simply capture the error and return a different component (e.g., one showing an error message).</p>
  <p>But, what I would really like is to make the tiles that throw an error disappear and not to take space in the grid (that is, no empty space should exist between tiles because of a tile that threw an error).</p>
  <p>I thought I had a solution, but it turns out it is not working. The idea was to store the tiles in state, and then make the error boundary execute a callback function that would remove the problematic tiles from the state. But, it seems the method that captures the error in the error boundary does not have access to React state.</p>
  <p>Following you can see the code for this idea:</p>
  <pre class="lang-js prettyprint-override"><code>const Tile = (props: { id: string }) =&gt; {
    if (parseInt(props.id) % 2 === 0) {
      throw new Error(&quot;error&quot;);
    }
  
    return &lt;div&gt;It worked!&lt;/div&gt;;
  };
  
  const SafeTile = (props: { id: string; onError: (id: string) =&gt; void }) =&gt; {
    return (
      &lt;ErrorBoundary
        fallback={&lt;div&gt;Error!&lt;/div&gt;}
        onError={() =&gt; props.onError(props.id)}
      &gt;
        &lt;Tile id={props.id} /&gt;
      &lt;/ErrorBoundary&gt;
    );
  };
  
  const App = (): JSX.Element =&gt; {
    const [tiles, setTiles] = useState&lt;{ [key: string]: JSX.Element }&gt;({});
  
    useEffect(() =&gt; {
      const removeTile = (id: string) =&gt; {
        const tilesCopy = {...tiles};
        delete tilesCopy[id];
        setTiles(tilesCopy);
      };
  
      setTiles({
        &quot;1&quot;: &lt;SafeTile id=&quot;1&quot; onError={removeTile} /&gt;,
        &quot;2&quot;: &lt;SafeTile id=&quot;2&quot; onError={removeTile} /&gt;,
        &quot;3&quot;: &lt;SafeTile id=&quot;3&quot; onError={removeTile} /&gt;
      });
    }, []);
  
    return (
      &lt;div&gt;
        {Object.entries(tiles).map(([id, tile]) =&gt; (
          &lt;div key={id}&gt;{tile}&lt;/div&gt;
        ))}
      &lt;/div&gt;
    );
  };
  </code></pre>
  <p>You can find a sandbox for this code here: <a href="https://codesandbox.io/s/thirsty-albattani-iupii" rel="nofollow noreferrer">https://codesandbox.io/s/thirsty-albattani-iupii</a></p>
  <p>Is what I am trying to achieve even possible? Am I just doing it the wrong way?</p>
  <p><strong>UPDATE</strong></p>
  <p>To make the desired solution more clear, I will show the expected DOM elements in the grid. Assuming a single row with three tiles, and the second tile throwing an error, I expect to have the following elements:</p>
  <pre class="lang-html prettyprint-override"><code>&lt;div class=&quot;row&quot;&gt;
    &lt;div class=&quot;column&quot; key=&quot;1&quot;&gt;
      &lt;SafeTile ...&gt;...&lt;/SafeTile&gt;
    &lt;/div&gt;
    &lt;div class=&quot;column&quot; key=&quot;3&quot;&gt;
      &lt;SafeTile ...&gt;...&lt;/SafeTile&gt;
    &lt;/div&gt;
  &lt;/div&gt;  
  </code></pre>
  <p><strong>UPDATE 2</strong></p>
  <p>Thanks to aseferov's answer, I found out I was not updating the state correctly. Simply changing the function <code>removeTile</code> to the following made the approach work.</p>
  <pre class="lang-js prettyprint-override"><code>    const removeTile = (id: string) =&gt; {
        setTiles(_tiles =&gt; {
          const tilesCopy = {..._tiles};
          delete tilesCopy[id];
          return tilesCopy;
        });
      };
  </code></pre>