Created
January 13, 2023 07:45
-
-
Save Clarity-89/49df2fd5eec7a96d404a88c49440c457 to your computer and use it in GitHub Desktop.
Display Warning for Unsaved Form Data on Page Exit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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]); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { forwardRef } from "react"; | |
import { useForm } from "react-hook-form"; | |
import { useAppState } from "../state"; | |
import { Button, Field, Form, Input, FormPrompt } from "../Forms"; | |
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 ( | |
<Form onSubmit={handleSubmit(saveData)} nextStep={"/education"}> | |
<FormPrompt hasUnsavedChanges={isDirty} /> | |
<fieldset> | |
<legend>Contact</legend> | |
<Field label="First name"> | |
<Input {...register("firstName")} id="first-name" /> | |
</Field> | |
<Field label="Last name"> | |
<Input {...register("lastName")} id="last-name" /> | |
</Field> | |
<Field label="Email"> | |
<Input {...register("email")} type="email" id="email" /> | |
</Field> | |
<Field label="Password"> | |
<Input {...register("password")} type="password" id="password" /> | |
</Field> | |
<Button ref={ref}>Next {">"}</Button> | |
</fieldset> | |
</Form> | |
); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const Home = () => { | |
return <div>Welcome to the home page!</div>; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useRef } from "react"; | |
import { BrowserRouter as Router, 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 "./styles.scss"; | |
import { Stepper } from "./Steps/Stepper"; | |
import { Home } from "./Home"; | |
export const App = () => { | |
const buttonRef = useRef(); | |
const onStepChange = () => { | |
buttonRef.current?.click(); | |
}; | |
return ( | |
<div className="App"> | |
<AppProvider> | |
<Router> | |
<div className="nav-wrapper"> | |
<NavLink to={"/"}>Home</NavLink> | |
<Stepper onStepChange={onStepChange} /> | |
</div> | |
<Route path="/"> | |
<Home /> | |
</Route> | |
<Route path="/contact"> | |
<Contact ref={buttonRef} /> | |
</Route> | |
<Route path="/education"> | |
<Education ref={buttonRef} /> | |
</Route> | |
<Route path="/about"> | |
<About ref={buttonRef} /> | |
</Route> | |
<Route path="/confirm"> | |
<Confirm /> | |
</Route> | |
</Router> | |
</AppProvider> | |
</div> | |
); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 <Prompt when={hasUnsavedChanges} message={onLocationChange} />; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment