Open2

next.jsでのオートセーブについて

Tomiaki MatsumuraTomiaki Matsumura

ウィンドウを閉じる(リロード)する際の処理

ウィンドウを閉じる際に何か処理を行いたい場合はbeforeunloadを使用する。

window.addEventListener("beforeunload", () => {
    // ウィンドウを閉じる際に行う処理
});

next.jsの場合はサーバサイドの処理とクライアントサイドの処理を書き分ける必要がありクライアントサイドの処理はuseEffectを使用する。

useEffect(() => {
    window.addEventListener("beforeunload", () => {
        // 処理
    });
    return () => window.removeEventListener("beforeunload", () => {
        // 処理
    });  // 最後はアンマウントが必要
}, []);

ここで以下のようにステートを保存する場合は問題が生じる。この場合useEffect内の処理はマウント時に一度だけ実行されるのだが保存される内容は閉じるタイミングに関らずこのマウント時に変数が保有している値になる。

const [val, setVal] = useState();

useEffect(() => {
    window.addEventListener("beforeunload", () => {
        save(val);
    });
    return () => window.removeEventListener("beforeunload", () => {
        save(val);
    });  // 最後はアンマウントが必要
}, []);

解決方法としてはステートが変更されるたびにイベントリスナーに登録しなおす以下の方法だ。

const [val, setVal] = useState();

useEffect(() => {
    window.addEventListener("beforeunload", () => {
        save(val);
    });
    return () => window.removeEventListener("beforeunload", () => {
        save(val);
    });  // 最後はアンマウントが必要
}, [val]);

無駄な処理が出てしまうのでどうにかしたい。

Tomiaki MatsumuraTomiaki Matsumura

ページ遷移の際の処理

next.jsでのページ遷移は通常のウェブページのページ遷移と異なるのでbeforeunload は発火してくれない。ページ遷移から戻ってきた時に変更した内容が残っていないのが問題なので、見方を変えれば「グローバルステートで値を保持する」などの解決策が浮かぶが、出来れば処理に一貫性を持たせたい。何かいい方法はないか?