Me enfrento a este comportamiento extraño cuando trato de actualizar el componente principal con una función establecida para el elemento secundario con accesorios. Este gancho es para abrir y cerrar el modal para editar un elemento.
//PARENT FILE //hook const [isEditModalOpen, setEditModalOpen] = useState(false) //more code... //modal {isEditModalOpen && <EditExcerciseModal setEditModalOpen={setEditModalOpen} isEditModalOpen={isEditModalOpen} />}y este es el codigo hijo
//CHILD FILE export const EditExcerciseModal = ({setEditModalOpen, excerciseInfo,fetchExcercisesFromRoutine}) //more code etc etc <div className="addExcerciseModalContainer"> <span onClick={() =>{ setEditModalOpen(false) }} className="xModal">X</span>Lo comprobé y el onClick está funcionando. si cambio el estado principal manualmente, Modal funciona bien y se cierra.
el caso extraño cuando funciona es cuando, en lugar de llamar a la función set, creo una función con un setTimeout sin tiempo como este:
function closeModal(){ setTimeout(() => { setEditModalOpen(false)}, 0); }¿algunas ideas? gracias por la ayuda
Es necesario crear una separación de preocupaciones. Un modal consta de tres partes.
Debería usar el gancho useState() y llamar a setEditModalOpen en el mismo componente que lo contiene.
Debe asegurarse de que está declarando y configurando el estado dentro del mismo componente.
// children would be the content of the modal const Modal = ({ children, selector, open, setOpen }) => { // we need the useEffect hook so that when we change open to false // the modal component will re-render and the portal will not be created useEffect(() => { setOpen(false); //provide useEffect hook with clean up. return () => setOpen(true); }, [selector]); return open ? createPortal(children, selector) : null; }; export const EditExerciseModal = ({ close }) => { return ( <div> {/* Instead of creating a handler inside this component we can create it in it's parent element */} <span onClick={close}>X</span> {/* Content */} </div> ); }; export const ModalBtn = () => { const [isEditModalOpen, setEditModalOpen] = useState(false); // this is where it all comes together, // our button element will keep track of the isEditModalOpen variable, // which in turn will update both child elements // when true useEffect hook will re-render Modal Component only now it "will" createPortal() // when our EditExerciseModal alls close it will set change the isEditModalOpen to false // which will be passed to the Modal component which // will then cause the component to re-render and not call createPortal() return ( <> <button onClick={() => setEditModalOpen(true)}>EditExerciseModal</button> {setEditModalOpen && ( <Modal open={isEditModalOpen} setOpen={setEditModalOpen} selector={'#portal'}> <div className='overlay'> <EditExerciseModal close={() => setEditModalOpen(false)} /> </div> </Modal> )} </> ); };