react-router
react-router copied to clipboard
[Bug]: useBlocker is not working
What version of React Router are you using?
"react-router-dom": "^6.22.3",
Steps to Reproduce
Create some routes with createBrowserRouter().
Create a Modal which shows something.
Example code
import React from "react";
import types, { MODAL_VARIANTS } from "./modal-types";
import styles from "./modal.module.scss";
import { useDispatch } from "react-redux";
import { CHANGE_MODAL_STATE } from "../../redux/reducers/alerts.reducer";
import { useBlocker, useLocation } from "react-router-dom";
const Modal = ({ show, type, variant = MODAL_VARIANTS.PRIMARY, ...rest }) => {
const Component = types[type];
const dispatch = useDispatch();
const location = useLocation();
const [pathName, setPathName] = React.useState("");
const whenToBlock = () => show;
let blocker = useBlocker(whenToBlock);
React.useEffect(() => {
if (location.pathname !== pathName) {
dispatch(CHANGE_MODAL_STATE({ show: false, type: null }));
}
}, [location.pathname, dispatch, pathName]);
React.useEffect(() => {
if (show) {
setPathName(location.pathname);
}
}, [show, location.pathname]);
if (show) {
return (
<div className={styles[variant]}>
<div
className={styles[`${variant}-modal-backdrop`]}
onClick={() => {
dispatch(CHANGE_MODAL_STATE({ show: false, type: null }));
console.log("blocker", blocker);
blocker.proceed();
}}
/>
<div className={styles[`${variant}-container`]}>
<Component {...rest} />
</div>
</div>
);
}
return null;
};
export default Modal;```
### Expected Behavior
When the show is false, the blocker should allow user to proceed.
### Actual Behavior
Throwing
Uncaught TypeError: blocker.proceed is not a function
when I close the modal by using this code
onClick={() => { dispatch(CHANGE_MODAL_STATE({ show: false, type: null })); console.log("blocker", blocker); blocker.proceed(); }}
The following is coming from console.log
{ location: undefined proceed: undefined reset: undefined state: "unblocked" }
You may have a stale closure problem - try using the value directly or using a callback with dependencies:
// Direct
let blocker = useBlocker(show);
// Callback
const whenToBlock = React.useCallback(() => show, [show]);
let blocker = useBlocker(whenToBlock);
Or, you my need to wait for the react state to flush out after dispatching your action. It's hard to say without a working reproduction.
I can confirm this as well
You may have a stale closure problem - try using the value directly or using a callback with dependencies:
// Direct let blocker = useBlocker(show); // Callback const whenToBlock = React.useCallback(() => show, [show]); let blocker = useBlocker(whenToBlock);Or, you my need to wait for the react state to flush out after dispatching your action. It's hard to say without a working reproduction.
I don't think this is the issue. I have tried this no difference.
Could either of you provide a minimal reproduction?
This issue has been automatically closed because we haven't received a response from the original author 🙈. This automation helps keep the issue tracker clean from issues that aren't actionable. Please reach out if you have more information for us! 🙂