DEV Community

Cover image for A Guide to Asynchronous result of React modal
Polarisiota
Polarisiota

Posted on

A Guide to Asynchronous result of React modal

This guide is about to get an asynchronous result from react modal.

Sometimes, we want to wait until user select a choice showing a modal, then proceed the following codes based on the user's choice.

Image description

Create the modal component

Modal.js



import React from 'react'
import './modal.css'

export default function Modal({isShow, onClose, message}) {
  return isShow && <div className="modal-overlay">
  <div className="modal">
    {message}
    <div className="modal-action">
      <button onClick={()=>onClose(true)}>OK</button>
      <button onClick={()=>onClose(false)}>Cancel</button>
    </div>
  </div>
  </div>
}


Enter fullscreen mode Exit fullscreen mode

Here I created a simple message modal component.
This modal returns a 'true/false' when a user clicks on OK or Cancel buttons.

Create the Modal Context Provider

context.js



import {createContext} from 'react';

export const ModalContext = createContext({
  show: () => {}
})


Enter fullscreen mode Exit fullscreen mode

Image description
ModalProvider.js



import React, {useState, useRef, useCallback, createContext, useEffect} from 'react'
import Modal from './Modal'
import {ModalContext} from './context'


export default function ModalProvider({children}) {
  const [isShow, setIsShow] = useState(false);
  const [message, setMessage] = useState("");
  const promiseRef = useRef();

  const show = useCallback((message) => {
    setIsShow(true);
    setMessage(message);

    return new Promise((resolve, reject) => {
      promiseRef.current = {resolve, reject};
    })
  }, [])  

  return <ModalContext.Provider value={{show}}>
    {children}
    <Modal isShow={isShow} onClose={(response) => {
    setIsShow(false);
    if (promiseRef.current) {
      promiseRef.current.resolve(response)
    }
    promiseRef.current = null
    }} message={message} />
  </ModalContext.Provider>
}


Enter fullscreen mode Exit fullscreen mode

app.js



import {useContext} from "react"
import './App.css'
import {ModalContext} from './modal/context'

export default function App() {
const modal = useContext(ModalContext);

const onShowButtonClick = async () => {
const result = await modal.show("Hello World!");
alert('result');
}
return (
<main>
<h1>React Asyncronous Confirm Modal</h1>
<div>
<p>Click the button to show a async confirm modal</p>
<button onClick={onShowButtonClick}>Show</button>
</div>
</main>
)
}

Enter fullscreen mode Exit fullscreen mode




Final Thoughts

This is a simple and useful way I've found to get the user's choice when I have to proceed the following codes related to the user's decision.
Live Code

Top comments (0)