需求
页面表格编辑之后,离开该页面需要弹框提示,是不是要保存修改的内容,保存失败停留在当前页面
思路
通过订阅model文件中的isEdit,changePage,isSave等状态,分别判断表格是否编辑了,是否切换页面,是否调用保存接口
model文件中的代码如下:
const Model = () => {
// 表格是否编辑了
const [isEdit, setIsEdit] = useState<boolean>(false)
// 是否切换页面
const [changePage, setChangePage] = useState<boolean>(false)
// 是否调用保存接口
const [isSave, setIsSave] = useState<boolean>(false)
// 弹出是否打开了
const [isOpen, setIsOpen] = useState<boolean>(false)
// 表格校验规则是否通过
const [checkTable, setCheckTable] = useState<boolean>(false)
// 表格保存的参数
const saveParams = useRef<{type: string; saveParam: string}>({type: '', saveParam: ''})
// 判断保存之后是否有后续操作
const nextOperation = useRef<boolean>(false)
const handleNo = () => {
setChangePage(true)
setCheckTable(true)
Modal.destroyAll()
}
// 调用接口,判断保存参数是否可以保存成功
const judgeSaveParams = async () => {
let result
if(saveParams.current?.type){
result = await apiService(saveParams.current)
if(result.code === 200 && result.data) {
setCheckTable(true)
}
return result.code === 200 && result.data
}
// 防止没有接入判断入参逻辑的页面报错
return true
}
const handleYes = async () => {
const status = await judgeSaveParams()
// 校验通过了切换页面
if(status) {
Modal.destroyAll()
setIsSave(true)
true
}
Modal.destroyAll()
}
const hasEditStatus = () => {
setIsOpen(true)
if(isOpen) return
Modal.confirm({
....,
footer: () => {
<Space>
<Button onClick={handleNo}>不保存</Button>
<Button onClick={handleYes} >保存</Button>
</Space>
},
afterClose: () => {
setIsOpen(false)
setCheckTable(false)
setChangePage(false)
saveParams.current = {type: '', saveParam: ''}
}
})
}
return {
isEdit,
...
}
}
export default Modal
页面通过引入这些状态,和更改状态的方法来达到判断是否切换页面的操作。
但是其中有一些问题
比如:这些状态其实都用useRef来声明比较好,这些状态不涉及页面的重新渲染,再就是在监听中因为一些异步操作,导致了重复监听,对监听数据的逻辑代码会有重复执行的风险
再就是:其实不用声明这么多状态的,状态声明多了,容易出问题,再就是维护起来比较消耗心智
如果改成这样,应该会好一些
const handleNo = () => {
// doing something
return false
}
const handleYes = () => {
// doing something
return true
}
const hasEditStatus = new Promise((resolve, reject) => {
setIsOpen(true)
if(isOpen) return
Modal.confirm({
....,
footer: () => {
<Space>
<Button onClick={() => { resolve(handleNo()) }}>不保存</Button>
<Button onClick={() => { resolve(handleYes()) }} >保存</Button>
</Space>
},
afterClose: () => {
setIsOpen(false)
setCheckTable(false)
setChangePage(false)
saveParams.current = {type: '', saveParam: ''}
}
})
})
这样就可以同步得到结果,不用去监听状态了