Por mi vida, no puedo entender por qué esto no funciona. Tengo un componente WorkoutCard:
Tarjeta de entrenamiento:
const key = require('weak-key'); function WorkoutCard({ workout }) { const { userID } = useContext(AuthContext); const [modalOpen, setModalOpen] = useState(false); const closeModalCallback = () => setModalOpen(false); return ( <div className="WorkoutCard" onClick={() => setModalOpen(true)}> <div className="header"> <h2>{workout.name}</h2> <h3>Days</h3> {workout.days.map((day) => { return ( <p key={key({})}>{day}</p> ) })} <button className="deleteButton" onClick={handleDelete}>Delete</button> </div> <div className="line"></div> <div className="exercises"> <h3>Exercises</h3> {workout.exercises.map((exercise) => { return ( <p key={key({})}>{exercise}</p> ) })} </div> <EditWorkoutModal key={key({})} modalOpen={modalOpen} closeModalCallback={closeModalCallback} /> </div> ); } export default WorkoutCard;Y tengo el componente EditWorkoutModal:
Modal.setAppElement('#root'); function EditWorkoutModal({ modalOpen, workout, closeModalCallback }) { const { userID } = useContext(AuthContext); return ( <Modal isOpen={modalOpen} className="editModal"> <div className="rightHalf"> <p className='closeButton' onClick={() => closeModalCallback()}>+</p> </div> </Modal> ) } export default EditWorkoutModalEl problema aquí es que closeModalCallback no cambia el estado en absoluto. Se llama, pero modalOpen aún se establece en verdadero.
Y esto es aún más confuso, porque tengo esta funcionalidad trabajando en otra parte de la aplicación. Tengo una página de entrenamientos que tiene los componentes WorkoutCard y Modal, y funciona de esta manera. Sin embargo, closeModalCallback en los modales de los componentes WorkoutCard no funcionará.
Los eventos onClick burbujean en el DOM. Por ejemplo, vea el siguiente fragmento (consulte la salida en la consola del navegador):
const App = () => { const parent = () => console.log("parent"); const child = () => console.log("child"); return <div onClick={parent}> <div onClick={child}>Click me</div> </div> } ReactDOM.createRoot(document.body).render(<App />); <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.0.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.0.0/umd/react-dom.production.min.js"></script>Lo anterior registra lo siguiente en la consola:
> child > parent Cuando hace clic en su elemento secundario, el evento de clic hace burbujear el DOM y finalmente llega a su div con la clase WorkoutCard , que activa el onClick que establece su estado de apertura modal en true . Puede evitar que el evento burbujee llamando a e.stopPropagation() en su botón de cierre modal:
onClick={(e) => { e.stopPropagation(); closeModalCallback(); }} De esta manera, el evento no aparecerá en su div principal y activará el onClick que está cambiando su estado.