¿Por qué obtengo dos registros de consola cuando debería ser solo uno? React js.
Tengo una sección simple en React que contiene dos botones, el logotipo y el banner. Al hacer clic, abro un modal simple desde un componente web. Ahora, cuando el usuario hace clic en “cancelar”, quiero que me muestre algo en la consola.
Problema: Cuando hago clic en el botón del logotipo, que abre el modal, y luego hago clic en “cancelar”, obtengo el log que quiero. Pero luego, cuando hago clic en el botón del banner, abro el modal y hago clic en “cancelar”, en lugar de obtener solo los registros relacionados con el botón del banner, obtengo ambos registros.
Mi código de demostración en vivo: live demo
import * as element from "./custom-element";
const Images = () => {
const [imgName, setImgName] = useState();
const [logo, setLogo] = useState();
const [banner, setBanner] = useState();
const elementRef = useRef(null);
const handleUseImage = () => {
switch (imgName) {
case "logo":
console.log("logo name", imgName);
break;
case "banner":
console.log("banner name", imgName);
break;
default:
}
};
useEffect(() => {
if (imgName) {
elementRef.current.addEventListener("cancel", function (e) {
handleUseImage(e);
});
}
}, [imgName]);
const handleLogo = () => {
setImgName("logo");
openModal();
};
const handleBanner = () => {
setImgName("banner");
openModal();
};
const openModal = () => {
elementRef.current.visible = true;
};
return (
<div classname="App">
<custom-element ref="{elementRef}"></custom-element>
<button onclick="{handleLogo}">Logo</button>
<button onclick="{handleBanner}">Banner</button>
<span>Logo url: {logo}</span>
<span>banner url: {banner}</span>
</div>
);
};
export default Images;
[][2]
¿Por qué obtengo ambos registros?
davy.ai
La razón por la que estás obteniendo ambos registros es porque estás agregando el event listener al
elementRef.current
cada vez que cambiaimgName
, pero no estás eliminando el event listener anterior. Esto significa que cuando abres el modal para la imagen del banner, aún tienes el event listener para la imagen del logo adjunto, lo que resulta en la visualización de ambos registros.Para solucionar esto, debes eliminar el event listener anterior antes de agregar uno nuevo. Puedes hacer esto manteniendo una referencia al event listener anterior y eliminándolo antes de agregar uno nuevo:
Aquí, estamos creando una función
cancelEventHandler
que llama ahandleUseImage
, y luego la agregamos como event listener para el evento"cancel"
. También estamos retornando una función de limpieza que elimina la misma funcióncancelEventHandler
del event listener cuando cambiaimgName
.Con este cambio, solo deberías ver los registros relacionados con el botón que se ha hecho clic.