Javascript 从网格中删除引发错误的React组件

Javascript 从网格中删除引发错误的React组件,javascript,reactjs,Javascript,Reactjs,我有一个React组件,它显示一个分片网格。某些平铺在尝试渲染时可能会抛出错误。使用错误边界,我可以简单地捕获错误并返回不同的组件(例如,显示错误消息的组件) 但是,我真正想要的是使抛出错误的磁贴消失,而不是在网格中占用空间(也就是说,由于抛出错误的磁贴,磁贴之间不应该存在空白) 我以为我有一个解决办法,但结果它不起作用。其思想是将tile存储在状态中,然后让错误边界执行回调函数,从状态中移除有问题的tile。但是,在错误边界中捕获错误的方法似乎无法访问React状态 下面您可以看到此想法的代码

我有一个React组件,它显示一个分片网格。某些平铺在尝试渲染时可能会抛出错误。使用错误边界,我可以简单地捕获错误并返回不同的组件(例如,显示错误消息的组件)

但是,我真正想要的是使抛出错误的磁贴消失,而不是在网格中占用空间(也就是说,由于抛出错误的磁贴,磁贴之间不应该存在空白)

我以为我有一个解决办法,但结果它不起作用。其思想是将tile存储在状态中,然后让错误边界执行回调函数,从状态中移除有问题的tile。但是,在错误边界中捕获错误的方法似乎无法访问React状态

下面您可以看到此想法的代码:

const Tile=(道具:{id:string})=>{
if(parseInt(props.id)%2==0){
抛出新错误(“错误”);
}
返回它的工作!;
};
const SafeTile=(props:{id:string;onError:(id:string)=>void}=>{
返回(
props.onError(props.id)}
>
);
};
常量App=():JSX.Element=>{
const[tiles,setTiles]=useState({});
useffect(()=>{
const removeTile=(id:string)=>{
const tilesCopy={…tiles};
删除TileCopy[id];
设置瓷砖(瓷砖镜);
};
地砖({
"1": ,
"2": ,
"3": 
});
}, []);
返回(
{Object.entries(tiles.map)([id,tile])=>(
{tile}
))}
);
};
您可以在此处找到此代码的沙箱:

我想要达到的目标是可能的吗?我只是做错了吗

更新

为了使所需的解决方案更加清晰,我将在网格中显示所需的DOM元素。假设一行有三个平铺,第二个平铺抛出错误,我希望有以下元素:


...
...
更新2

多亏了aseferov的回答,我发现我没有正确地更新状态。只需将函数
removeTile
更改为以下内容,即可实现该方法

constremovetile=(id:string)=>{
setTiles(_tiles=>{
const tilesCopy={…\u tiles};
删除TileCopy[id];
返回瓷砖镜;
});
};

如果您将grid div放入SafeTile中,它将在出现错误时被删除

const App = (): JSX.Element => {

  const [tiles, setTiles] = useState<number[]>([1,2,3]);


  return (
    <div>
      {tiles.map((id) => (
        <SafeTile key={id} id={id} onError={() => {
          setTiles(_tiles => _tiles.filter(t => t !== id))
        }}/>
      ))}
    </div>
  );
};


const SafeTile = (props: { id: string; onError: () => void }) => {
  return (
    <ErrorBoundary
      fallback={<></>}
      onError={props.onError}
    >
      <div>
        <Tile id={props.id} />
      </div>
    </ErrorBoundary>
  );
};
const-App=():JSX.Element=>{
const[tiles,setTiles]=useState([1,2,3]);
返回(
{tiles.map((id)=>(
{
setTiles(_tiles=>_tiles.filter(t=>t!==id))
}}/>
))}
);
};
const SafeTile=(props:{id:string;onError:()=>void})=>{
返回(
);
};

好主意,但我个人认为这可能根本不是一个“Reactish”结构,因为子组件影响父组件


更具反应性的结构(这将减少出错的可能性和类似本例的变通方法)将让父组件首先决定应该渲染哪个子组件,然后渲染被认为足够的对象。

我个人只需将错误处理函数传递给Tile组件,并将抛出错误的风险函数包装在try/catch中。在catch中,您调用传递的错误处理程序。但这不会使列消失——它只会使单元格为空(带有片段),对吗?我更新了我的问题,让它更清楚。啊,如果是这样的话。首先,使用要渲染的所有单元创建一个数组,然后按数量对它们进行剪切columns@Promet99我之前尝试过,但是当瓷砖组件在阵列中时,它们还没有“渲染”。因此,似乎不可能知道组件(单元格)渲染后是否会抛出错误,因此无法提前过滤掉它们。这不仅仅是片段,还需要放入
@betabando。瓷砖似乎是由props.id过滤的。父组件可以访问其子组件的props.id。因此,可以在父组件内过滤数据,过滤后的数据将用于使tilesI也有相同的感觉。我考虑在组件树的某个位置运行一些“验证”,以确定需要显示哪些分片。但是,这似乎并不能解决瓷砖抛出错误的情况。我想,由于验证,出错的可能性会降低,但我希望找到一个始终有效的解决方案,即使存在错误。