Description
useConfirm
uses ReactDOM.render
to inject the confirmation dialog into the HTML.
react/src/Dialog/ConfirmationDialog.tsx
Lines 161 to 168 in 72f0ec6
This triggers a warning in the console when in development mode:
Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot
While the warning states that the whole app will behave like it's running React 17, this isn't really the case - only the dialog will. This is because the call to render
creates a whole new React app instance which only contains the dialog. However, this still isn't great and we definitely should resolve this.
The obvious solution is to just use createRoot
instead, but it seems like there must be a more elegant alternative here than to create an entirely new React application. What if we could come up with a way to extract the Portal
component into a usePortal
hook, allowing rendering arbitary JSX into the default portal from any hook? Something like this:
function useConfirm() {
const renderIntoPortal = usePortal()
return () => new Promise(_resolve => {
const resolve = (result) => {
_resolve(result)
renderIntoPortal(null)
}
renderIntoPortal(
<ConfirmationDialog onClose={resolve(false)}>
<Button onClick={resolve(true)}>Confirm</Button>
</ConfirmationDialog>
)
})
}
I'm not sure if this is actually technically possible though - maybe I'll try and come up with a POC this week.