はじめに
ユーザーが何かしらのデータを入力をした状態で画面の遷移を制御したい場合がある。
「リンク、戻る、進む、リロード、ホームボタン、タブを閉じる」を押したときにユーザーに遷移して良いかアラートを出したい。
開発環境
- react-router v5.2.0
リンクでの遷移、戻る、進む
リンクでの遷移や「戻る」「進む」ボタンでの制御はreact-router
のPrompt
で制御できます。
when
がtrue
の時に実行されます。
messageが返す文字列はカスタム可能です。
特定のページに対しての遷移を制御することもできます。
react-router v6系だとPrompt
は対応していない模様。
import React, { useState } from 'react'
import { Prompt } from 'react-router'
const App = () => {
const [bool, setBool] = useState(true)
return (
<div>
・・・略
<Prompt
when={!bool}
message={(location) => {
return location ? 'ページ遷移できません' : true
}}
/>
</div>
)
}
export default App
リロード、ホームボタン、タブを閉じる
「リロード、ホームボタン、タブを閉じる」はonbeforeunload
で制御します。
こちらは最新のブラウザでカスタムメッセージは使えないようです。
カスタムフックを作って制御しています。
import { useEffect } from 'react'
const useOnbeforeUnload = (bool) => {
useEffect(() => {
window.onbeforeunload = () => (bool ? null : true)
}, [bool])
}
export default useOnbeforeUnload
追記
実装できたぜ!と思ったらiOSで死んでた。
react-router
が制御するページ遷移と戻る進むは問題なかったけど、beforeunload
が対応していなかった。
参考資料