21
loading...
This website collects cookies to deliver better user experience
type State =
| null
| DELETE_REQUEST
| DELETE_CONFIRMED
| DELETE_PENDING
| DELETED
const [state, setState] = useState<State>(null);
const handleDelete = () => {
if (state !== null) return;
setState('DELETE_REQUEST');
};
const handleConfirm = () => {
setState('DELETE_CONFIRMED');
};
useEffect(() => {
if (state === 'DELETE_CONFIRMED') {
setState('DELETE_PENDING');
deleteRemote().then(() => {
// setting to null resets to initial state.
setState(null);
});
}
}, [state]);
return (
<>
{state === 'DELETE_REQUEST' && (
<ConfirmDialog onConfirm={handleConfirm} />
)}
{state === 'DELETE_PENDING' && <Loading />}
{state === null && <Button onClick={handleDelete}>Delete now</Button>}
</>
);
I believe an asynchronous prompt is possible in react and will solve many issues.
// 👍 Consider this API
const [child, setChild] = useState();
setChild(<strong>Why is he putting JSX into state?</strong>)
// instead of this api
const [show, setShow] = useState(false);
setShow(true)
return (show && <strong>as usual</strong>)
const [promptContent, confirm] = useState();
const onClick = () => {
confirm(<strong>Are you sure?</strong>)
}
return promptContent
const useConfirm = () => {
const promiseRef = useRef();
const [child, setChild] = useState();
const confirm = (jsxElement) => {
setChild(child);
// we return a promise and store
// the resolve
return new Promise((resolve, reject) => {
promiseRef.current = {resolve, reject}
});
}
const handleConfirm = () => {
// we hide the prompt by setting the jsx to null
setChild(null)
// we resolve the promise
promiseRef.current.resolve()
}
}
const onClick = async () => {
if (await confirm(...)) {
// ...
}
}
21