Reputation: 11853
I have a React/Redux application that takes the user through some basic setup steps and the last page is a page where live data is captured and recorded. I don't want the user to be able to Ctrl+R
, F5
or Ctrl+F5
and refresh the page. Instead, the only way I want them to leave the page is to click a "Stop recording" button.
Currently, the application is built using a single HomeScreenComponent
and I swap out the components of the page depending on the mode that the application is in. So for example, if it's in setup mode, it'll show Component A and if it's in record mode, it'll show Component B.
As it stands right now, if a user is in record mode, they are able to do Ctrl+R
and refresh the page, taking you back to setup mode.
How do I prevent the user from refreshing the page and leaving without clicking the "Stop recording" button? There are two ways I can imagine achieving this: either disable refreshing (but only in record mode) OR allow for refreshing but have it do nothing (and navigate back to my record mode state).
App.tsx
function App() {
return (
<Provider store={store}>
<ConnectedRouter history={history}>
<React.Fragment>
<Route exact path="/"><Redirect to="/app" /></Route>
<Route exact path="/app" component={HomeScreenContainer} />
</React.Fragment>
</ConnectedRouter>
</Provider>
);
}
export default App;
HomeScreenComponent
export class HomeScreenComponent extends React.PureComponent<HomeScreenProps, FormState> {
render() {
return (
<div>
<Container>
{this.props.mode === SETUP_MODE && <SetupContainer />}
{this.props.mode === RECORD_MODE && <RecordingContainer />}
</Container>
</div>
);
}
}
In my Redux state, the default mode for the application is SETUP_MODE
const defaultState: HomeScreenState = {
mode: SETUP_MODE,
...// other stuff here
};
Any help would be greatly appreciated.
Upvotes: 1
Views: 3172
Reputation: 876
For class components
componentDidMount() {
window.addEventListener('beforeunload', this.handleBeforeUnload);
}
componentWillUnmount() {
window.removeEventListener('beforeunload', this.handleBeforeUnload);
}
handleBeforeUnload = (event) => {
const message = "Are you sure you want to leave?";
event.preventDefault();
event.returnValue = message;
return message;
};
For functional components
useEffect(() => {
const handleBeforeUnload = (event) => {
const message = "Are you sure you want to leave?";
event.preventDefault();
event.returnValue = message;
return message;
};
window.addEventListener('beforeunload', handleBeforeUnload);
return () => {
window.removeEventListener('beforeunload', handleBeforeUnload);
};
}, []);
Upvotes: 0
Reputation: 6504
You can not prevent page refresh, but you can show the warning/alert to user if user tries to leave the page with some pending changes.
if (somePendingChange) {
window.onbeforeunload = () => true
} else {
window.onbeforeunload = undefined
}
It will show an alert to user if condition is true.
Upvotes: 4
Reputation: 1832
I don't think you can prevent the action of refresh from a browser and this not adviced also.
What you can do its store a variable as a cookie or in localStorage in order to be able to know, when the user refresh, if he was on record or setup mode just before the refresh.
Upvotes: 0