我使用的是具有四个阶段的步进器,需要阻止浏览器的后退按钮,该按钮功能正常。
父组件
const CreateSpace = ({}) => {
const blocker = useBlocker(
({ currentLocation, nextLocation }) =>
formData.projectName !== '' &&
currentLocation.pathname !== nextLocation.pathname
);
return (
<>
<div>
<Modal
className="error-message-modal"
isOpen={blocker?.state === 'blocked'}
>
<ModalBody className="p-3 text-center">
<h4>{promptMessage}</h4>
</ModalBody>
<div className="text-center mb-2 d-flex justify-content-center">
<Button color="secondary" onClick={() => blocker?.reset()}>
<IntlMessages id="cai.cancel-label" />
</Button>
<Button
color="secondary btn-multiple-state"
onClick={() => blocker?.proceed()}
>
<IntlMessages id="cai.add-cart-label" />
</Button>
</div>
</Modal>
</div>
<Stepper
steps={[
{ label: 'Overview' },
{ label: 'Services' },
{ label: 'Create permission group' },
{ label: 'Review' },
]}
activeStep={activeStep}
styleConfig={stepStyleConfig}
/>
{activeStep === constants.STEP_REVIEW ? (
<Review <--- child component
blocker={blocker} <--- passing blocker as prop
/>
) : (
''
)}
)}
</>
);
};
将 blocker 作为 prop 传递给子组件
子组件
现在,提交按钮被放置在步进器的最后一步中。单击时,将触发 API,收到响应后,用户将被重定向到仪表板页面。
const ReviewStep = (props) => {
const {blocker, response } = props;
const navigate = useNavigate();
const submitFormData = () => {
if (Object.keys(formData).length > 0) {
dispatch(postSolutionSpace(formData));
}
if (response && blocker.state === 'blocked') {
blocker?.reset?.(); <--- blocker Reset not working
navigate(`${adminRoot}solution-space/dashboard`);
blocker?.proceed?.();<--- blocker proceed not working
}
}
/* form start*/
}
在控制台日志中我可以看到畅通状态,但导航没有发生。
回答我的问题。 父组件
const [leavePage, setLeavePage] = useState(false);
const blocker = useBlocker(({ currentLocation, nextLocation }) =>
!leavePage && formData.projectName !== '' &&
currentLocation.pathname !== nextLocation.pathname
);
/* unblock navigation when form submit */
useEffect(() => {
if (blocker.state === 'blocked' && leavePage) {
blocker?.proceed?.(); /* be care full accessing proceed(), always use inside guard claus */
}
}, [blocker,leavePage]);
子组件
const ReviewStep = (props) => {
const {blocker, response } = props;
const navigate = useNavigate();
const submitFormData = () => {
if (Object.keys(formData).length > 0) {
dispatch(postSolutionSpace(formData));
setLeavePage(true); <-- set flag true on form submit
}
navigate(`/solution-space/dashboard`);
}
/* form start*/
}