例如,用户编辑表单的某个值,在未保存之前,却无意中点击了其他页面链接,前往新的页面后,之前编辑的数据将全部丢失。
为了阻止类似的现象发生,可以使用 react-router-dom 提供的 Prompt 组件。Prompt 会自动监视用户是否离开页面。 如果满足某个条件,它会在允许离开之前显示警告。
Prompt 带有两个属性,when 和 message,
当 when 为true且用户离开当前页面时显示message。
export interface PromptProps {
message: string | ((location: H.Location, action: H.Action) => string | boolean);
when?: boolean | undefined;
}
代码举例
useLeavePage(hooks)
在src目录下创建hooks文件夹
hooks/useLeavePage.ts
import {useState} from 'react';
import {useHistory} from 'react-router-dom';
import {Modal} from 'antd';
const useLeavePage = () => {
const history = useHistory();
// 是否已经退出
const [hasQuit, setHasQuit] = useState(false);
// 值是否改变
const [valueChange, setValueChange] = useState(false);
// 退出提示, 用useCallback有问题
const handleLeavePage = (location, action) => {
// action
if (action === 'REPLACE' || (action === 'PUSH' && !hasQuit)) {
setHasQuit(true);
Modal.confirm({
title: '退出设置提示',
content: '直接退出将不再对页面修改内容进行保存,请确认操作',
okText: '退出',
onOk: () => {
history.push(location);
setHasQuit(false);
},
onCancel: () => {
setHasQuit(false);
},
});
return false;
}
return valueChange;
};
return {
valueChange,
setValueChange,
handleLeavePage,
};
};
export default useLeavePage;
使用方法
import {FunctionComponent, useCallback, useEffect, useState} from 'react';
import {Prompt} from 'react-router-dom';
import classnames from 'classnames';
import {isEmpty} from 'lodash-es';
import {Form, Input, Radio, Button, Space, toast} from 'antd';
import useLeavePage from '@/hooks/useLeavePage';
import styles from './styles.module.less';
const FormItem = Form.Item;
const DEFAULT_DATA = {
age: 10
};
const CustomFrom = props => {
const [form] = Form.useForm();
const {
valueChange,
setValueChange,
handleLeavePage
} = useLeavePage();
// 初始化获取数据
const initForm = useCallback(
() => {
form.setFieldsValue(DEFAULT_DATA);
},
[form, getAlarmStorageConfig, type]
);
// 提交表单
const handleFinish = useCallback(
async () => {
const {cleanType, perCameraNum} = await form.validateFields();
const params = {
cleanType,
perCameraNum: +perCameraNum,
type,
};
// TODO
},
[form, type, updateAlarmStorageConfig]
);
// 监听form值变化
const handleValuesChange = useCallback(
() => {
setValueChange(true);
},
[setValueChange]
);
// 恢复默认设置
const handleReset = useCallback(
() => {
form.setFieldsValue(DEFAULT_DATA);
toast.success({message: '恢复默认设置成功'});
setValueChange(true);
},
[form]
);
useEffect(
() => {
initForm();
},
[initForm]
);
return (
<div className={classnames(styles['alarm-storage-config-form'])}>
<h2>个人信息</h2>
<Form
form={form}
labelWidth={144}
labelAlign="left"
onValuesChange={handleValuesChange}
>
<FormItem
name="age"
label="年龄"
rules={[{required: true, message: '年龄不可为空'}]}
>
<Input style={{width: 120}} />
</FormItem>
</Form>
<Space>
<Button
type="primary"
htmlType="submit"
loading={loading}
onClick={handleFinish}
>
保存
</Button>
<Button type="default" htmlType="submit" onClick={handleReset}>
重置
</Button>
</Space>
<Prompt when={valueChange} message={handleLeavePage} />
</div>
);
};
export default CustomFrom;

5432

被折叠的 条评论
为什么被折叠?



