reactjs - 在 React Router v6 中,如何在离开页面/路由之前检查表单是否脏
问题描述
以下是我正在使用的软件包版本。
React version - 16.13.1
react-router-dom version - 6.0.0-beta.0
react-redux version 7.2.0
Material UI version 4.11.0
isDirty
当用户试图离开当前页面时,如何/什么是检查表单(已更改)的最佳方法?如果表格是isDirty
.
我将从内部获取数据useEffect()
并使用 redux reducer 来呈现 UI。
我应该声明一个变量来保留原始获取的数据以进行脏检查吗?
这就是我正在做的,但它不能正常工作。
组件.js
useEffect(() => {
props.fetchUserInfo();
})
动作.js
export function fetchUserInfo() {
return (dispatch) => {
dispatch({type: USER_INITIALSTATE, {Name: 'abc', Age: 20}}
)
}
}
userReducer.js
const initialState = {
processing: false,
success: false,
fail: false,
Profile: {}
}
let oriState;
let State;
const UserReducer = (state = initialState, action) => {
if (action.type === USER_INITIALSTATE) {
oriState = {Profile: action.data};
State = {...state, Profile: action.data};
return {...state, Profile: action.data};
} else if (action.type === OTHERS_ACTION) {
//update field change
return {...state, xxx}
}
}
export const userIsDirty = state => {
if (oriState && State) {
return JSON.stringify(oriState.Profile) !== JSON.stringify(State.Profile);
}
return false;
};
export default UserReducer;
因此,在我的组件中,我调用userIsDirty
返回 isDirty 布尔值,但我还没有弄清楚如何捕获离开页面事件并将其用作触发器来进行脏表单检查。
那么如何检测离开当前页面呢?我在useEffect return(component umount)上尝试了一些东西,但是道具没有获得更新的INITIALSTATE状态(意味着我将获得Profile:{}),因为它只运行一次,但是如果我添加useEffect可选数组参数,我得到一个无限循环(也许我设置错了?)。
useEffect(() => {
props.fetchUserInfo();
return () => {
console.log(props); //not getting initial state object
};
}, []);
我这样做是正确的方式吗?我错过了什么?是否有更好/正确的解决方案来实现我想要的?
更新
谢谢@gdh,useBlocker
是我想要的。我正在使用它来弹出一个确认对话框。
我将分享我完整的代码框,我相信这可能对将来的某人有所帮助。
解决方案
这个答案使用路由器 v6。
- 您可以使用usePrompt。
- 当您转到另一条路线(即安装时)时,usePrompt 将显示确认模式/弹出窗口。
- 当您尝试关闭浏览器时,带有消息的通用警报。它在内部处理 beforeunload
usePrompt("Hello from usePrompt -- Are you sure you want to leave?", isBlocking);
- 您可以使用useBlocker
- useBlocker 将在尝试导航离开时(即卸载时)简单地阻止用户
- 当您尝试关闭浏览器时,带有消息的通用警报。它在内部处理 beforeunload
useBlocker(
() => "Hello from useBlocker -- are you sure you want to leave?",
isBlocking
);
- 您也可以使用beforeunload。但是你必须做你自己的逻辑。在此处查看示例
推荐阅读
- javascript - 使用 substr 方法制作字数计数器的问题
- c# - C# JSON 序列化/反序列化 - 输入问题
- c# - 使用 autofac 在 .net 核心中使用参数(服务)注册上下文
- regex - 如何 grep 7 位数字并在 uniqe 中对它们进行排序
- python - 检查序列是否包含非连续子序列的最快方法?
- winapi - 如何使用多色渐变禁用多边形中的中心颜色?
- c++ - 迭代器作为映射值出错
- audio - AVAudioEngine 是否支持递归路由?
- unity3d - 从 n 时间开始统一动画,而不是从开始
- javascript - JavaScript 字符串拆分:固定宽度与分隔性能