用戶不小心要離開到編輯到一半的內容,如果可以跳個提示問是否要離開編輯,不失為一個貼心的好作法
這個的重要性不用我多說,直接進入重點。
用戶要離開會有兩種情況:
1. Url 變更或是關掉視窗
2. 關閉某個 component
設計概念
第一種情況比較單純,可以用 browser 預設的行為來解決(關鍵字:onbeforeunload),只要可以讓用戶觸發任何可輸入的元件時,指定 function 給 window.onbeforeunload 即可
第二種情況就需要自己實作一些功能:
1. 設一個 Boolean flag 決定目前是否是 dirty 狀態
2. 一個對應的 Modal 或是提示元件告知用戶正要離開是否放棄編輯
上 Code 👏
useUnsavedChange.tsx
import React, { useMemo, useState, useCallback } from 'react';import UnsavedChangeModal from '../components/modals/UnsavedChangeModal';
function useUnsavedChange() {
const [isDirty, setIsDirty] = useState(false);
const [showModal, setShowModal] = useState(false);
const [confirm, setConfirm] = useState<any>(() => () => undefined);
const checkUnsaved = useCallback(
({ confirm }) => {
if (isDirty) {
//show modal
setShowModal(true);
setConfirm(() => confirm);
return;
}
confirm();
},
[isDirty]
);
const CheckUnsavedModal = useMemo(() => {
return showModal ? (
<UnsavedChangeModal
onCancel={() => setShowModal(false)}
onConfirm={() => {
confirm();
setShowModal(false);
setIsDirty(false);
}}
/>
) : null;
}, [confirm, showModal]);
return {
setIsDirty: (isDirty) => {
if (isDirty) {
window.onbeforeunload = (e) => 'Discard Change?';
} else {
window.onbeforeunload = null;
}
setIsDirty(isDirty);
},
checkUnsaved,
isDirty,
CheckUnsavedModal,
};
}
export default useUnsavedChange;
這裡面實作了我上述提到的幾個重點:
1. 在用戶可以做操作的地方 (input, checkbox 之類的),可以透過 expose 出去的 setIsDirty 來達到同時設定 dirty flag 成 true 和指定 onbeforeunload,或是清除 dirty flag
2. 透過呼叫 checkUnsaved 可以觸發去檢查 dirty flag 是否為真,來決定要不要顯示客製的 Modal ,引導用戶繼續編輯或是離開
應用範例
歡迎有任何問題都可以直接透過社群媒體找我!
如果在工程師職涯或想轉職工程師上有任何想討論或是任何我可以幫忙,也歡迎在這裡進一步聯繫
找到更多我的資訊可以到這 mhtsai