react-admin icon indicating copy to clipboard operation
react-admin copied to clipboard

TypeError: navigator.block using the warnWhenUnsavedChanges prop in Form

Open HenryPineda opened this issue 2 years ago • 1 comments

After upgrading to version 4 I have an issue with using the warnWhenUnsavedChanges prop in Form.

What you were expecting:

Able to use the warnWhenUnsavedChanges prop in the form component and get an alert when leaving a page that a has a form with data so no data is lost but instead saved before leaving the page.

What happened instead:

When trying to edit a record I get the Error "navigator.block is not a function".

Steps to reproduce:

1- User the Form Component and add the warnWhenUnsavedChanges. 2- Add TextInput fields. 3- Add info in the fields. 4- Get the error.

Environment Mac

  • React-admin version: 4.3.2
  • Last version that did not exhibit the issue (if applicable): 3*
  • React version: 18.2.0
  • Browser: Chrome
  • Stack trace (in case of a JS error):

Uncaught TypeError: navigator.block is not a function at index.js:121476:33 at commitHookEffectListMount (index.js:159924:26) at commitPassiveMountOnFiber (index.js:161700:13) at commitPassiveMountEffects_complete (index.js:161665:9) at commitPassiveMountEffects_begin (index.js:161652:7) at commitPassiveMountEffects (index.js:161640:3) at flushPassiveEffectsImpl (index.js:163813:3) at flushPassiveEffects (index.js:163758:14) at commitRootImpl (index.js:163709:5) at commitRoot (index.js:163456:5)

var useWarnWhenUnsavedChanges = function (enable, formRootPathname, control) { // react-router v6 does not yet provide a way to block navigation // This is planned for a future release // See https://github.com/remix-run/react-router/issues/8139 var navigator = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(react_router_dom__WEBPACK_IMPORTED_MODULE_1__.UNSAFE_NavigationContext).navigator; var location = (0,react_router_dom__WEBPACK_IMPORTED_MODULE_1__.useLocation)(); var translate = (0,i18n__WEBPACK_IMPORTED_MODULE_2_.useTranslate)(); var a = (0,react_hook_form__WEBPACK_IMPORTED_MODULE_3_.useFormState)(control ? { control: control } : undefined), isSubmitSuccessful = a.isSubmitSuccessful, isSubmitting = a.isSubmitting, dirtyFields = a.dirtyFields; var isDirty = Object.keys(dirtyFields).length > 0; var initialLocation = (0,react__WEBPACK_IMPORTED_MODULE_0.useRef)(formRootPathname || location.pathname); (0,react__WEBPACK_IMPORTED_MODULE_0_.useEffect)(function () { if (!enable || !isDirty) return; var unblock = navigator.block(function (tx) { var newLocationIsInsideForm = tx.location.pathname.startsWith(initialLocation.current); if (!isSubmitting && (newLocationIsInsideForm || isSubmitSuccessful || window.confirm(translate('ra.message.unsaved_changes')))) { unblock(); tx.retry(); } }); return unblock; },

HenryPineda avatar Sep 14 '22 18:09 HenryPineda

FYI we do use warnWhenUnsavedChanges in our examples, and especially in the simple example which is the one we encourage you to fork on codesandbox to provide a reproduction case.

If you try it at https://codesandbox.io/s/github/marmelab/react-admin/tree/master/examples/simple you will see that it works fine. (see PostEdit or CommentEdit for instance)

In your case it might be that you are using a custom router or the wrong version of react-router (you need to use v6).

If you are convinced that there is something wrong on the react-admin side, then please fork this sandbox and provide a reproduction case.

slax57 avatar Sep 15 '22 09:09 slax57

Metoo getting this error after the upgrade

from package.json "@mui/styles": "^5.6.2", "@testing-library/jest-dom": "^5.16.4", "@testing-library/react": "^13.1.1", "@testing-library/user-event": "^13.5.0", "axios": "^0.26.1", "patch-package": "^6.4.7", "ra-data-django-rest-framework": "^0.2.1", "ra-data-fakerest": "^4.0.1", "ra-data-simple-rest": "^4.0.2", "ra-in-memory-jwt": "^1.0.0", "ra-input-rich-text": "^4.2.0", "react": "^18.0.0", "react-admin": "^4.0.1", "react-dom": "^18.0.0", "react-google-recaptcha-v3": "^1.10.0", "react-icons": "^4.4.0", "react-loading": "^2.0.3", "react-query-devtools": "^2.6.3", "react-redux": "^8.0.2", "react-scripts": "5.0.1", "web-vitals": "^2.1.4"

Please prioritize this with the fix. Temp Fix I have removed that props useWarnWhenUnsavedChanges

neps-in avatar Sep 27 '22 13:09 neps-in

@neps-in please provide a reproduction if you want us to take a look at it.

fzaninotto avatar Sep 27 '22 15:09 fzaninotto

It seems react-router 6.4.0 broke this, see https://github.com/remix-run/react-router/issues/9262

fzaninotto avatar Sep 27 '22 15:09 fzaninotto

Quick fix in userland: set a resolution in your package.json to force react-router < 6.4.0:

"resolutions": {
   "react-router": "6.3.0"
}

fzaninotto avatar Sep 27 '22 18:09 fzaninotto

Apparently, navigator.block is not coming back any time soon.

https://github.com/remix-run/react-router/issues/8139

We have no other choice but to test if the feature exists, and if not, throw an error inviting the developer either to downgrade react-router, or to remove the useWarnWhenUnsavedChanges hook.

fzaninotto avatar Sep 30 '22 15:09 fzaninotto

Note that this bug only appears if you use a custom Router.

fzaninotto avatar Oct 17 '22 16:10 fzaninotto