A React hook and provider for managing unsaved changes in web applications, providing an easy way to prevent users from accidentally navigating away from a page with unsaved work.
useUnsavedChangesHook: Easily track changes within a component.UnsavedChangesProvider: Manage global unsaved changes state across your application.- Customizable Prompt: Configure the message shown to users when unsaved changes are detected.
- Blocking Navigation: Integrates with browser's
beforeunloadevent to prevent accidental page closes or reloads.
You can install the hook using npm or yarn:
npm install react-unsaved-changes-hook
# or
yarn add react-unsaved-changes-hookThis package requires react and react-dom as peer dependencies. Make sure you have them installed in your project:
npm install react react-dom
# or
yarn add react react-domWrap your application or a part of it with UnsavedChangesProvider to enable unsaved changes tracking.
import React from "react";
import ReactDOM from "react-dom/client";
import { UnsavedChangesProvider } from "react-unsaved-changes-hook";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<UnsavedChangesProvider
// Optional: Custom message for the browser's beforeunload dialog
alertMessage="You have unsaved changes. Are you sure you want to leave?"
>
<App />
</UnsavedChangesProvider>
</React.StrictMode>
);alertMessage?: string: An optional custom message to display in the browser'sbeforeunloadconfirmation dialog. If not provided, a default browser message will be used.children: React.ReactNode: The components that will have access to the unsaved changes context.
Use the useUnsavedChanges hook in any functional component to signal whether there are unsaved changes.
import React, { useState } from "react";
import { useUnsavedChanges } from "react-unsaved-changes-hook";
function MyForm() {
const [value, setValue] = useState("");
const [isChanged, setIsChanged] = useState(false);
// Set unsaved changes status
useUnsavedChanges(isChanged);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setValue(e.target.value);
setIsChanged(true); // Mark as changed when input is modified
};
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Save logic here
console.log("Saving:", value);
setIsChanged(false); // Mark as unchanged after saving
};
return (
<form onSubmit={handleSubmit}>
<input type="text" value={value} onChange={handleChange} />
<button type="submit">Save</button>
{isChanged && <span>Unsaved changes!</span>}
</form>
);
}
export default MyForm;hasUnsavedChanges: boolean: A boolean indicating whether the current component or form has unsaved changes. Whentrue, thebeforeunloadevent will be triggered, prompting the user.
The provider component that manages the global state for unsaved changes.
interface UnsavedChangesProviderProps {
alertMessage?: string;
children: React.ReactNode;
}A hook to signal to the UnsavedChangesProvider whether the current component has unsaved changes.
hasUnsavedChanges: boolean: A flag that, whentrue, indicates there are unsaved changes and will trigger the browser'sbeforeunloadevent.
Contributions are welcome! Please feel free to open an issue or submit a pull request.
- Fork the repository.
- Create your feature branch (
git checkout -b feature/AmazingFeature). - Commit your changes (
git commit -m 'Add some AmazingFeature'). - Push to the branch (
git push origin feature/AmazingFeature). - Open a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.