91在线一级黄片|91视频在线观看18|成人夜间呦呦网站|91资源欧美日韩超碰|久久最新免费精品视频一区二区三区|国产探花视频在线观看|黄片真人免费三级片毛片|国产人无码视频在线|精品成人影视无码三区|久久视频爱久久免费精品

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
離開(kāi)頁(yè)面前,如何防止表單數(shù)據(jù)丟失?

本文介紹了如何實(shí)現(xiàn)一個(gè)FormPrompt組件,在用戶嘗試離開(kāi)具有未保存更改的頁(yè)面時(shí)發(fā)出警告。文章討論了如何使用純JavaScript和beforeunload事件處理這類情況,以及使用React Router v5中的Prompt組件和useBeforeUnload以及unstable等React特定解決方案。向用戶添加一個(gè)確認(rèn)對(duì)話框,詢問(wèn)他們?cè)诰哂形幢4姹韱胃牡那闆r下是否確認(rèn)重定向是一種良好的用戶體驗(yàn)實(shí)踐。通過(guò)顯示此提示,用戶將意識(shí)到他們有未保存的更改,并允許在繼續(xù)重定向之前保存或丟棄它們的工作。

武宣ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)公司的ssl證書(shū)銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:18980820575(備注:SSL證書(shū)合作)期待與您的合作!

下面是正文:

在今天的數(shù)字化環(huán)境中,為涉及表單提交的 Web 應(yīng)用程序提供最佳用戶體驗(yàn)非常重要。用戶常見(jiàn)的一個(gè)煩惱來(lái)源是由于意外離開(kāi)頁(yè)面而丟失未保存的更改。

本文將演示如何實(shí)現(xiàn)一個(gè) FormPrompt 組件,當(dāng)用戶嘗試離開(kāi)具有未保存更改的頁(yè)面時(shí),會(huì)發(fā)出警報(bào),從而有效地提高整體用戶體驗(yàn)。我們將討論如何使用純 JavaScript 處理此類情況,使用 React Router v5 中的 Prompt 組件以及在 React Router v6 中使用 useBeforeUnload 和 unstable_useBlocker 鉤子的特定解決方案。

應(yīng)用程序的最終版本可以在 CodeSandbox 上進(jìn)行測(cè)試,代碼可在 GitHub 上獲得。

使用 beforeunload 事件檢測(cè)頁(yè)面離開(kāi)

我們創(chuàng)建 FormPrompt 組件,在其中添加 beforeunload 事件的監(jiān)聽(tīng)器。此事件將在用戶離開(kāi)頁(yè)面之前觸發(fā)。通過(guò)在事件上調(diào)用 preventDefault 方法,我們可以觸發(fā)瀏覽器的確認(rèn)對(duì)話框。僅當(dāng)表單具有未保存的更改(由 hasUnsavedChanges 屬性指示)時(shí),才會(huì)激活此對(duì)話框。

// FormPrompt.js

import { useEffect } from "react";

export const FormPrompt = ({ hasUnsavedChanges }) => {
  useEffect(() => {
    const onBeforeUnload = (e) => {
      if (hasUnsavedChanges) {
        e.preventDefault();
        e.returnValue = "";
      }
    };
    window.addEventListener("beforeunload", onBeforeUnload);
    return () => {
      window.removeEventListener("beforeunload", onBeforeUnload);
    };
  }, [hasUnsavedChanges]);
};

作為示例,我們將在表單的 Contact 步驟中使用此組件:

// Steps/Contact.js

import { forwardRef } from "react";
import { useForm } from "react-hook-form";
import { useAppState } from "../state";
import { Button, Field, Form, Input } from "../Forms";
import { FormPrompt } from "../FormPrompt";

export const Contact = forwardRef((props, ref) => {
  const [state, setState] = useAppState();
  const {
    handleSubmit,
    register,
    formState: { isDirty },
  } = useForm({
    defaultValues: state,
    mode: "onSubmit",
  });

  const saveData = (data) => {
    setState({ ...state, ...data });
  };

  return (
    
Contact
); });

當(dāng)在表單字段中輸入數(shù)據(jù)并在保存更改之前嘗試重新加載頁(yè)面或?qū)Ш降酵獠縐RL時(shí),瀏覽器將顯示確認(rèn)對(duì)話框。

使用React Router 5防止頁(yè)面導(dǎo)航

這個(gè)組件已經(jīng)足夠好用于我們的應(yīng)用程序,因?yàn)樗乃许?yè)面都是表單的一部分。然而,在實(shí)際情況下,這并不總是如此。為了使我們的示例更具代表性,我們添加一個(gè)名為 Home 的新路由,它將重定向到表單之外。 Home 組件很簡(jiǎn)單,只顯示一個(gè)主頁(yè)問(wèn)候語(yǔ)。

// Home.js

export const Home = () => {
  return 
Welcome to the home page!
; };

我們還需要對(duì) App 組件進(jìn)行一些調(diào)整,以適應(yīng)這條新路由。

// App.js

import { useRef } from "react";
import {
  BrowserRouter as Router,
  Routes,
  Route,
  NavLink,
} from "react-router-dom";
import { AppProvider } from "./state";
import { Contact } from "./Steps/Contact";
import { Education } from "./Steps/Education";
import { About } from "./Steps/About";
import { Confirm } from "./Steps/Confirm";
import { Stepper } from "./Steps/Stepper";
import { Home } from "./Home";

export const App = () => {
  const buttonRef = useRef();

  const onStepChange = () => {
    buttonRef.current?.click();
  };

  return (
    
Home
} /> } /> } /> } /> } />
); };

我們可以看到當(dāng)我們?cè)诒砀裰休斎胄畔⒉?dǎo)航到主頁(yè)時(shí),輸入的數(shù)據(jù)不會(huì)被保存,也不會(huì)出現(xiàn)任何確認(rèn)對(duì)話框。這是因?yàn)閷?dǎo)航由React Router處理,不會(huì)觸發(fā) beforeunload 事件,使瀏覽器API在這種情況下無(wú)效。幸運(yùn)的是,React Router v5提供了 Prompt 組件,以在離開(kāi)未保存更改的頁(yè)面之前警告用戶。該組件接受兩個(gè)props: when 和 message 。 when 屬性是一個(gè)布爾值,用于確定是否應(yīng)該顯示提示,而 message 屬性表示向用戶顯示的文本。

使用 Prompt 時(shí),導(dǎo)航到主頁(yè)路由時(shí)行為正確,但是當(dāng)用戶輸入表單數(shù)據(jù)并進(jìn)入下一步時(shí),確認(rèn)對(duì)話框也會(huì)出現(xiàn)。這是不希望的,因?yàn)槲覀冊(cè)趯?dǎo)航到下一步時(shí)保存表單數(shù)據(jù)。

為了解決這個(gè)問(wèn)題,我們需要驗(yàn)證下一個(gè) URL 是否是表單步驟之一,然后再檢查未保存的更改??梢允褂?nbsp;message 屬性來(lái)實(shí)現(xiàn)這一點(diǎn),它也可以是一個(gè)函數(shù)。該函數(shù)的第一個(gè)參數(shù)是下一個(gè)位置。如果函數(shù)返回 true ,則允許轉(zhuǎn)換到下一個(gè) URL;否則,它可以返回一個(gè)字符串來(lái)顯示提示。

// FormPrompt.js

import { useEffect } from "react";
import { Prompt } from "react-router-dom";

const stepLinks = ["/contact", "/education", "/about", "/confirm"];

export const FormPrompt = ({ hasUnsavedChanges }) => {
  useEffect(() => {
    const onBeforeUnload = (e) => {
      if (hasUnsavedChanges) {
        e.preventDefault();
        e.returnValue = "";
      }
    };
    window.addEventListener("beforeunload", onBeforeUnload);

    return () => {
      window.removeEventListener("beforeunload", onBeforeUnload);
    };
  }, [hasUnsavedChanges]);

  const onLocationChange = (location) => {
    if (stepLinks.includes(location.pathname)) {
      return true;
    }
    return "You have unsaved changes, are you sure you want to leave?";
  };

  return ;
};

通過(guò)這些更改,我們可以安全地在表單步驟之間導(dǎo)航,并在嘗試離開(kāi)未保存更改的表單時(shí)收到警告。

使用 React Router 6 防止頁(yè)面導(dǎo)航

件已被移除,而 unstable_usePrompt 鉤子在 6.7.0 版本中被添加。正如其名稱所示,該鉤子的實(shí)現(xiàn)可能會(huì)發(fā)生變化,尚未記錄文檔。但是,它應(yīng)該適用于我們的使用情況。

我們可以使用這個(gè)鉤子來(lái)復(fù)制版本5中 Prompt 組件的行為,但首先,我們需要調(diào)整我們的 App 組件以使用新的數(shù)據(jù)路由器,因?yàn)樗鼈兪?nbsp;unstable_usePrompt 鉤子工作所必需的。

// App.js

import { useRef } from "react";
import { createBrowserRouter, RouterProvider, Outlet } from "react-router-dom";
import { AppProvider } from "./state";
import { Contact } from "./Steps/Contact";
import { Education } from "./Steps/Education";
import { About } from "./Steps/About";
import { Confirm } from "./Steps/Confirm";
import { Stepper } from "./Steps/Stepper";
import { Home } from "./Home";

export const App = () => {
  const buttonRef = useRef();

  const onStepChange = () => {
    buttonRef.current?.click();
  };

  const router = createBrowserRouter([
    {
      element: (
        <>
          
          
        
      ),
      children: [
        {
          path: "/",
          element: ,
        },
        {
          path: "/contact",
          element: ,
        },
        { path: "/education", element:  },
        { path: "/about", element:  },
        { path: "/confirm", element:  },
      ],
    },
  ]);

  return (
    
); };

我們使用 createBrowserRouter 函數(shù)來(lái)創(chuàng)建路由器。請(qǐng)注意, Stepper 沒(méi)有單獨(dú)的路徑,所有其他路由都是它的子路由。它作為布局組件,在每個(gè)頁(yè)面上呈現(xiàn)。每個(gè)頁(yè)面的內(nèi)容顯示在特殊的 Outlet 組件的位置。為了簡(jiǎn)化 App 邏輯,我們還將主頁(yè)導(dǎo)航鏈接移動(dòng)到 Stepper 中。

設(shè)置完成后,我們現(xiàn)在可以實(shí)現(xiàn)重定向阻止功能。我們首先通過(guò)在 FormPrompt 中使用在6.6版本中引入的 useBeforeUnload 鉤子來(lái)替換 onbeforeunload 邏輯。

// FormPrompt.js

import { useEffect, useCallback, useRef } from "react";
import { useBeforeUnload } from "react-router-dom";

const stepLinks = ["/contact", "/education", "/about", "/confirm"];

export const FormPrompt = ({ hasUnsavedChanges }) => {
  useBeforeUnload(
    useCallback(
      (event) => {
        if (hasUnsavedChanges) {
          event.preventDefault();
          event.returnValue = "";
        }
      },
      [hasUnsavedChanges]
    ),
    { capture: true }
  );

  return null;
};

這個(gè)改變簡(jiǎn)化了我們組件的邏輯。現(xiàn)在,我們可以添加一個(gè)自定義的 usePrompt 鉤子,并像版本5中的 Prompt 組件一樣使用它。

// FormPrompt.js

import { useEffect, useCallback, useRef } from "react";
import {
  useBeforeUnload,
  unstable_useBlocker as useBlocker,
} from "react-router-dom";

const stepLinks = ["/contact", "/education", "/about", "/confirm"];

export const FormPrompt = ({ hasUnsavedChanges }) => {
  const onLocationChange = useCallback(
    ({ nextLocation }) => {
      if (!stepLinks.includes(nextLocation.pathname) && hasUnsavedChanges) {
        return !window.confirm(
          "You have unsaved changes, are you sure you want to leave?"
        );
      }
      return false;
    },
    [hasUnsavedChanges]
  );

  usePrompt(onLocationChange, hasUnsavedChanges);
  useBeforeUnload(
    useCallback(
      (event) => {
        if (hasUnsavedChanges) {
          event.preventDefault();
          event.returnValue = "";
        }
      },
      [hasUnsavedChanges]
    ),
    { capture: true }
  );

  return null;
};

function usePrompt(onLocationChange, hasUnsavedChanges) {
  const blocker = useBlocker(hasUnsavedChanges ? onLocationChange : false);
  const prevState = useRef(blocker.state);

  useEffect(() => {
    if (blocker.state === "blocked") {
      blocker.reset();
    }
    prevState.current = blocker.state;
  }, [blocker]);
}

useBlocker 鉤子接受布爾值或阻止函數(shù)作為其參數(shù),類似于 Prompt 組件中的 message 屬性。該函數(shù)的一個(gè)參數(shù)是下一個(gè)位置,我們使用它來(lái)確定用戶是否正在離開(kāi)我們的表單。如果是這種情況,我們利用瀏覽器的 window.confirm 方法顯示一個(gè)對(duì)話框,詢問(wèn)用戶確認(rèn)重定向或取消它。最后,我們?cè)?nbsp;usePrompt 鉤子中抽象出阻止邏輯并管理阻止器的狀態(tài)。

我們可以通過(guò)導(dǎo)航到聯(lián)系步驟,填寫(xiě)一些字段并單擊主頁(yè)導(dǎo)航項(xiàng)來(lái)測(cè)試 FormPrompt 是否按預(yù)期工作。我們會(huì)看到一個(gè)確認(rèn)對(duì)話框,詢問(wèn)我們是否要離開(kāi)該頁(yè)面。

總結(jié)

總之,為未保存的表單更改實(shí)現(xiàn)確認(rèn)對(duì)話框是增強(qiáng)用戶體驗(yàn)的重要實(shí)踐。本文演示了如何創(chuàng)建一個(gè) FormPrompt 組件,當(dāng)用戶嘗試離開(kāi)具有未保存更改的頁(yè)面時(shí),該組件會(huì)向用戶發(fā)出警告。我們探討了如何使用純JavaScript處理這種情況,使用 beforeunload 事件以及在React中使用React Router v5中的 Prompt 組件和React Router v6中的 useBeforeUnload 和 unstable_useBlocker 鉤子。通過(guò)將此功能合并到您的表單中,你可以幫助用戶避免失去未保存的工作而感到沮喪。

本文轉(zhuǎn)載自微信公眾號(hào)「大遷世界」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系大遷世界公眾號(hào)。


文章名稱:離開(kāi)頁(yè)面前,如何防止表單數(shù)據(jù)丟失?
當(dāng)前鏈接:http://m.jiaoqi3.com/article/dppscgi.html