27
loading...
This website collects cookies to deliver better user experience
const [opened, setOpened] = useState(false);
const launch = useLaunchMissile();
return (
<div>
<button onClick={() => setOpened(true)}>Launch missile</button>
<ConfirmationModal
opened={opened}
onConfirm={launch}
onClose={() => setOpened(false)}
/>
</div>
)
// `./context/DialogProvider`
import {useState, createContext, useMemo} from 'react';
export const DialogContext = createContext({});
export function DialogProvider({ children }) {
const [Dialog, setDialog] = useState(); // Dialog has type ReactNode
const context = useMemo(() => ({ setDialog }), []);
return (
<>
<DialogContext.Provider value={context}>{children}</DialogContext.Provider>
{Dialog}
</>
);
}
// `./hooks/use-dialog.js`
import { useContext, useCallback, useEffect } from 'react';
import { DialogContext } from '../context/DialogProvider';
export function useDialog() {
const { setDialog } = useContext(DialogContext);
const close = useCallback(() => setDialog && setDialog(null), [setDialog]);
const add = useCallback((node) => setDialog && setDialog(node), [setDialog]);
useEffect(() => {
return close;
}, [close]);
return {
add,
close,
};
}
// ./hooks/use-user-consent.jsx
import { useDialog } from './use-dialog';
import { ConfirmationDialog } from '../components/ConfirmationDialog';
export function useUserConsent() {
const { add, close } = useDialog();
return () =>
new Promise((resolve) => {
const onClose = (accepted) => {
close();
resolve(accepted);
};
add(
<ConfirmationDialog
onAccept={() => onClose(true)}
onDismiss={() => onClose(false)}
/>,
);
});
}
true
if the user clicked confirm
, and resolve to false otherwise. If you wish to test the code, here is a dumb implementation of the ConfirmationDialog component:// `./components/ConfirmationDialog.jsx`
export function ConfirmationDialog({ onDismiss, onAccept }) {
return (
<div>
<div>Are you sure?</div>
<button onClick={onAccept}>OK</button>
<button onClick={onDismiss}>Close</button>
</div>
)
}
// App.js
import { DialogProvider } from './context/DialogProvider'
import { ConsentTest } from './components/ConsentTest'
function App() {
return (
<DialogProvider>
<ConsentTest />
</DialogProvider>
);
}
export default App;
// `./components/components/ConsentTest.jsx
import { useCallback } from "react";
import { useUserConsent } from "../hooks/use-user-consent";
export function ConsentTest() {
const hasApproval = useUserConsent();
const callback = useCallback(async () => {
const userConfirmed = await hasApproval();
alert(userConfirmed);
}, [hasApproval]);
return <button onClick={callback}>Test</button>
}
hasApproval
" method to have a configurable prompt message.