简体   繁体   English

React 功能组件 - 如何在离开组件时要求用户确认

[英]React functional component - how to ask user to confirm when leaving a component

I have a quite traditional problem but I haven't found a solution thus far searching around on Stackoverflow.我有一个非常传统的问题,但到目前为止我还没有找到解决方案,在 Stackoverflow 上四处搜索。

My problem is like this.我的问题是这样的。 I have a functional component which renders a form (using Formik).我有一个呈现表单的功能组件(使用 Formik)。 This component is rendered inside another Tab component that allows user to switch to another view.该组件呈现在另一个 Tab 组件内,允许用户切换到另一个视图。 The UI also have another menu, buttons which also allow user to switch to different UI.用户界面还有另一个菜单,按钮也允许用户切换到不同的用户界面。 Whenever a user changes a field in the form, I have a global flag in Redux store that marks it as dirty form.每当用户更改表单中的字段时,我在 Redux 商店中都有一个全局标志,将其标记为脏表单。

What I want to achieve is that when user click on another tab or go to another UI view when form is dirty, system will show a dialog to confirm.我想要实现的是,当用户点击另一个选项卡或 go 到另一个 UI 视图时,当表单变脏时,系统将显示一个对话框进行确认。 If user agrees, he loses his changes and go to another view, if he doesn't, he will stay at current view with the form.如果用户同意,他将丢失他的更改和 go 到另一个视图,如果他不同意,他将留在当前视图和表单。

My current solution is that I have to add the confirming logic to every event handler that could bring user to another view such as Tab click, Menu click and this is tedious.我目前的解决方案是我必须向每个事件处理程序添加确认逻辑,这些事件处理程序可以将用户带到另一个视图,例如 Tab 单击、菜单单击,这很乏味。 Not to mention if the UI change in the future with more events for example more buttons, we have to keep adding this confirm logic to the onClick handler.更不用说如果 UI 在未来发生更多事件(例如更多按钮)的变化,我们必须继续将此确认逻辑添加到 onClick 处理程序。

I also tried using useEffect as below in this component that returns a clean up function where I can add the confirm logic.我还尝试在此组件中使用如下所示的 useEffect,它返回清理 function,我可以在其中添加确认逻辑。 This could show up the confirm dialog but it won't prevent React to unmount this form component and user ends up still go to another view.这可能会显示确认对话框,但它不会阻止 React 卸载此表单组件,并且用户最终仍会 go 到另一个视图。

useEffect(() => {
  return () => {
    //confirm logic here
  }
}, [])

Is there a way for functional component handle this confirming logic itself?有没有办法让功能组件自己处理这个确认逻辑?

These are some post I looked at but don't really find the answer.这些是我看过的一些帖子,但并没有真正找到答案。 This one suggest using React router which we don't use in our project.这个建议使用我们在项目中不使用的 React 路由器。 The route actually doesn't change when user leave this form component.当用户离开这个表单组件时,路由实际上并没有改变。 Show warning message before unmouting React component 在卸载 React 组件之前显示警告消息

Thanks for any advice!感谢您的任何建议!

In short, no.简而言之,不。 That's a drawback of single page applications.这是单页应用程序的缺点。 Since the page isn't actually being navigated, you can't use the native beforeunload event, and since you're not using a router you can't customize routing in that respect either.由于页面实际上并未被导航,因此您不能使用本机beforeunload事件,并且由于您没有使用路由器,因此您也无法在这方面自定义路由。 What you can do is wrap these navigation components with a custom component so you don't need to repeat yourself everywhere.您可以做的是用自定义组件包装这些导航组件,这样您就不需要在所有地方重复自己。

const MyCustomTabComponent = (props) => {
  function navigateIfNotDirty(tabIndex) {
    // Check if it's safe to navigate
    props.onTabChange?.() // Maybe allow passing another callback in as well
    // Finally navigate
  }
  
  return <TabComponent {...props} onTabChange={navigateIfNotDirty} />
}

I don't know the actual syntax of the components you're using, but that should give you the idea.我不知道您正在使用的组件的实际语法,但这应该能让您有所了解。

The actual logic will be specific to the UI library you're using, if any.实际逻辑将特定于您使用的 UI 库(如果有)。 By your question, it seems like you already figured out how to cancel navigation given a condition, it's just a matter of abstracting that logic into a new, reusable component.根据您的问题,您似乎已经想出了如何在给定条件的情况下取消导航,这只是将该逻辑抽象为一个新的可重用组件的问题。

If the navigation components are already custom instead of being from a library, then it's even easier.如果导航组件已经是自定义的而不是来自库,那么它就更容易了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM