React中如何正确处理Promise:点击非Ficha元素时结束Promise
问题解决
核心问题是启动Promise时的卡片点击事件会冒泡到document,被waitForEvent的监听器捕获,导致加else后立刻触发resolve。解决思路是忽略触发Promise的初始点击事件,只处理后续的点击操作。
具体修改步骤
- 在
handleClick中接收点击事件,将原生事件对象传递给waitForEvent,用于后续排除初始点击。 - 修改
waitForEvent函数,添加参数接收初始事件,在事件处理器中先判断是否为初始点击,若是则直接跳过。 - 无论后续点击的是ficha元素还是其他元素,都移除事件监听器并resolve Promise,满足“点击任意非初始元素都结束Promise”的需求。
修改后的完整代码
import React from "react"; import { CardMovUser } from "../components/Cards/CardMovement"; const CardMovementContainer = ({ movement, index, selectedCard, waitingForEvent, onCardClick, onEventComplete, isMyTurn }) => { const handleClick = (event) => { if (!isMyTurn) return; console.log("Clicked card", index); onCardClick(index); // Solo iniciar el evento de espera si `waitingForEvent` no está activo. if (!waitingForEvent) { waitForEvent("click", "[data-ficha-id]", event.nativeEvent).then(() => { console.log("Evento completado"); onEventComplete(); }); } }; const waitForEvent = (eventType, selector, initialEvent) => { return new Promise((resolve) => { const handler = (event) => { // 忽略触发Promise的初始卡片点击事件 if (event === initialEvent) return; console.log("Evento detectado en:", event.target); const fichaElement = event.target.closest(selector); // 移除监听器,避免内存泄漏 document.removeEventListener(eventType, handler); console.log("Evento removido"); if (fichaElement) { console.log("Ficha seleccionada: ", fichaElement); } else { console.log("点击了非ficha元素,结束Promise"); } // 无论点击什么,都resolve结束Promise resolve(); }; console.log(`Añadiendo listener para ${eventType} en elementos que coincidan con ${selector}`); document.addEventListener(eventType, handler); }); }; return ( <CardMovUser img_url={movement.movimiento.img_url} movetype={movement.movimiento.movement} handleClick={handleClick} clicked={selectedCard === index} /> ); }; export default CardMovementContainer;
说明
- 初始点击卡片时,
event.nativeEvent被传递给waitForEvent,当监听器捕获到这个事件时会直接跳过,不会触发resolve。 - 后续的任何点击(ficha或其他元素)都会触发监听器,移除监听后resolve Promise,完美匹配需求。
- 确保了事件监听器被及时移除,避免内存泄漏问题。
内容的提问来源于stack exchange,提问作者Simon Celoria
相关产品推荐
相关产品推荐

