[英]Remove dynamic rendered element from dom in ReactJS
目前我有一个看起来像这样的反应组件:
const GeraCard = (cards, cart = false) => {
return cards.map((v, i) => {
return (
<div key={i} className={styles.card}>
<div onClick={() => urlRender(v.url)} className={styles.cardContent}>
<div>
<span className={styles.cardTitulo}>{v.Nome}</span>
</div>
<div>
<span className={styles.cardData}>{v.Data}</span>
<span className={styles.cardAtivos}>{v.Ativos} ativo(s)</span>
</div>
{cart ? <div>R$ {FormatCapital(v.Capital)}</div> : null}
</div>
<span className={styles.trash}>
<FontAwesomeIcon
icon={faTrash}
color={"#3c3c3c77"}
onClick={(e) => {
e.persist()
TrashHandler(v.Nome, e)
}}
/>
</span>
</div>
);
});
};
基于卡片数组,它呈现如下内容:
每当我单击垃圾桶按钮时,我都会向后端发出请求,编辑数据库中的列表并根据现在更新的“卡片”重新呈现组件。 问题是这需要一段时间才能发生,所以我想要一种方法在我的后端完成它的工作时立即从 dom 中删除它。
有点像
{show ? renderCompoennt : null}
我尝试使用香草 javascript 从垃圾桶中抓取父级,这将是我要删除的卡,但结果无法预测,而且速度也很慢。
我最近的尝试是这样的:
const GeraCard = (cards, cart = false) => {
return cards.map((v, i) => {
const [show, setShow] = useState(true);
return (
<div key={i}>
{show ?
<div className={styles.card}>
<div onClick={() => urlRender(v.url)} className={styles.cardContent}>
<div>
<span className={styles.cardTitulo}>{v.Nome}</span>
</div>
<div>
<span className={styles.cardData}>{v.Data}</span>
<span className={styles.cardAtivos}>{v.Ativos} ativo(s)</span>
</div>
{cart ? <div>R$ {FormatCapital(v.Capital)}</div> : null}
</div>
<span className={styles.trash}>
<FontAwesomeIcon
icon={faTrash}
color={"#3c3c3c77"}
onClick={(e) => {
setShow(false);
e.persist()
TrashHandler(v.Nome, e)
}}
/>
</span>
</div> :
null
}
</div>
);
});
};
但反应不会让我这样做。 即使它很快,每次删除一个项目时,react 都会抱怨“渲染的钩子更少”并使应用程序崩溃。
有谁知道解决方法? 谢谢!
您正在尝试做一些Optimistic UI ,其中您假设您的操作将成功,并在对后端的请求完成之前立即反映预期/假设的 state。 这将代替显示一些进度/忙碌指示器,如微调器,直到服务器完成操作。
您的代码中的第一个问题和直接问题 - 它违反了hooks 的规则,即 Hooks 只能在顶层使用(永远不要在循环、条件等)中使用。
第二个问题是您正在利用 vanilla JS 直接操作 DOM; 这通常是 MV* 框架中的反模式,在这里也是如此。 相反,我建议在您的数据 model 中进行管理; 像这样的东西:
deleted
的属性,则重写您的.map
处理程序以返回null
。setState
将deleted: true
属性添加到点击的卡片现在,您将获得一个忽略已删除卡的重新渲染,并向后端发出请求,所有这些都在 React 数据 model 中。 确保您处理以下复杂性:
祝你好运,编码愉快!
问题是,在第一次渲染中,您有 {cards.length} 调用来挂钩 GeraCard 中的“useState”,但在删除一张卡片后,您将有 {cards.length-1} 调用来挂钩“useState”。 作为 React 文档 state:
不要在循环、条件或嵌套函数中调用 Hook。 相反,请始终在 React function 的顶层使用 Hooks。 通过遵循此规则,您可以确保每次渲染组件时都以相同的顺序调用 Hook。 这就是允许 React 在多个 useState 和 useEffect 调用之间正确保留 Hooks 的 state 的原因。
您应该将 map 回调的内容提取到单独的组件中。
const GeraCards = (cards, cart = false) => {
return cards.map((v, i) =>
<GeraCard card={v} index={i} cart={cart} />
);
};
const GeraCard = ({ card, index, cart }) => {
const [show, setShow] = useState(true);
const v = card;
return (
<div key={index}>
{show ?
<div className={styles.card}>
<div onClick={() => urlRender(v.url)} className={styles.cardContent}>
<div>
<span className={styles.cardTitulo}>{v.Nome}</span>
</div>
<div>
<span className={styles.cardData}>{v.Data}</span>
<span className={styles.cardAtivos}>{v.Ativos} ativo(s)</span>
</div>
{cart ? <div>R$ {FormatCapital(v.Capital)}</div> : null}
</div>
<span className={styles.trash}>
<FontAwesomeIcon
icon={faTrash}
color={"#3c3c3c77"}
onClick={(e) => {
setShow(false);
e.persist()
TrashHandler(v.Nome, e)
}}
/>
</span>
</div> :
null
}
</div>
);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.