Un poco de contexto: necesito una función de espera asíncrona o Promise/Resolve para devolver el botón de elección que selecciona un usuario. La razón por la que lo necesito de esta manera es porque estoy llamando a una función deletePost desde dentro de un componente de Publicación secundario específico y necesito un Modal que exista en un nivel de componente principal para solicitar al usuario que confirme Eliminar o Cancelar. Luego necesito que esa decisión se devuelva al componente de Publicación secundario para continuar con el proceso de eliminación o cancelarlo según el botón en el que haga clic el usuario en el Modal.
La razón por la que tiene que ser así es porque todos los datos de la publicación que quiero eliminar existen en ese nivel de componente secundario de Publicación, por lo que toda la funcionalidad para eliminar una publicación debe estar en el nivel de componente de Publicación y estoy buscando vincule eso a un Modal en un nivel principal superior que me permitirá confirmar o cancelar ese proceso de eliminación con solo hacer clic en un botón en el modal
import React, { useState } from "react"; const Example = async () => { const [modalOpen, setModalOpen] = useState(false); const toggleModal = async () => { // Opens Modal setModalOpen(!modalOpen); let decision = null; // should be "delete" or "cancel" for return /* This toggleModal() function will be called from within a child component's deletePost() function to prompt a user for confirmation of deletion or cancellation. Once the modal opens up, I believe I need some kind of async await function HERE to wait on a click decision from the user and then return that selected value all the way back to the deletePost() function that was called from within the child Post component. */ return decision; }; const modalStyle = { display: modalOpen ? "block" : "hidden", }; return ( <div> <button onClick={toggleModal}>Open Modal</button> <Modal style={modalStyle}> {/* How to link these buttons to the async await function above */} <button>Delete</button> <button>Cancel</button> </Modal> {posts.map((post, index) => ( <Post key={post.id} post={post} toggleModal={toggleModal} /> ))} </div> ); }; export default Example;
No estoy seguro de su caso de uso exacto, pero si desea saber si el usuario seleccionó Cancel
o Confirm
, puede hacerlo adjuntando un evento onClick
separado en esos dos botones.
import React, { useState } from "react"; const Example = async () => { const [modalOpen, setModalOpen] = useState(false); const toggleModal = () => { // Opens Modal setModalOpen(!modalOpen); }; const handleConfirm = () => { //confirm logic } const handleCancel = () => { //cancel logic } const modalStyle = { display: modalOpen ? "block" : "hidden", }; return ( <div> <button onClick={toggleModal}>Open Modal</button> <Modal style={modalStyle}> <button onClick={handleConfirm}>Confirm</button> <button onClick={handleCancel}>Cancel</button> </Modal> </div> ); }; export default Example;
De esta manera, mantiene todos los métodos separados y ni siquiera necesita usar async await, es decir, usar para que el usuario haga clic en uno de esos botones.
Editar: Agregué este codeandbox basado en mi comprensión del comentario de op.
Acabo de publicar un paquete para manejar su caso.
Instalación:
npm install use-awaitable-component
Uso:
import React, { useState } from "react"; import useAwaitableComponent from "use-awaitable-component"; const Example = async () => { const [awaitModalStatus, awaitModalExec, awaitModalResolve, awaitModalReject, awaitModalReset] = useAwaitableComponent(); const modalOpen = awaitModalStatus === 'awaiting' // Show modal while awaiting const awaitModal = async () => { try { const decission = await awaitModalExec(); console.log(decission); } finally { awaitModalReset() } }; const modalStyle = { display: modalOpen ? "block" : "hidden", }; return ( <div> <button onClick={awaitModal}>Open Modal</button> <Modal style={modalStyle}> <button onClick={() => awaitModalResolve('delete')}>Delete</button> <button onClick={() => awaitModalReset()}>Cancel</button> </Modal> {posts.map((post, index) => ( <Post key={post.id} post={post} toggleModal={awaitModal} /> ))} </div> ); }; export default Example;