输入一些数据后在离开页面之前警告用户特别是在ReactJS中

问题描述

我正在创建一个页面用户需要在其中输入详细信息以将产品添加到产品列表中。如果用户在输入表单中的某些数据后不小心将其移出了该页面,则在移出之前,用户必须进行确认。但是我正在为这个要求而苦苦挣扎。我正在使用react-hook-form将数据存储在JSON服务器中。

我正在使用状态leave,如果它为true,则在移出其他内容之前提醒用户

const [leave,setLeave] = useState(false);

现在,我不知道在离开之前在何处以及如何使用此状态显示警报框。 这是我要呈现的表格。

render (
<Form onSubmit={handleSubmit(onSubmit)}>
   <Form.Row>
       <Form.Group as={Col} className="mr-5">
       <Form.Label column>Product Name</Form.Label>
       <Form.Control
            name="productName"
            placeholder="Enter product Name"
            required
            ref={register}
            />
       </Form.Group>
   </Form.Row>
   <Button variant="success" type="submit" className="text-white mt-5">
            Add New Product
   </Button>
</Form>

<Prompt when={Leave} message="Are you sure you want to leave ?" /> {/*Here I have promted*/}
);

为简单起见,我只给出了一个输入字段。现在,下面将给出onSubmit的函数定义。

const onSubmit = (formData) => {
    setLeave(true);   //here I am setting this true
    axios.post("http://localhost:4000/products",formData);
    navigation.push({
        pathname: "/productList",state: { added: "pass" },});
};

这在我提交表单时有效,但 我想在用户单击后退按钮或任何导航链接提示

解决方法

要中断导航时,

when必须为true。

我会将您的变量重命名为isDirty,初始化为false。自从我开始这样命名我的布尔标志后,我发现我的脑子需要做些少的工作来了解它的用途。

在第一次更改表单值时将其翻转到true。可以简单地将useEffect作为依赖项的formData吗?检查其尚未翻转,以防止不必要的渲染。

当您从提交的内容中获得200时,将其翻转回false,以进行后续导航。

我不认为在您当前的onSubmit中触发提示之前,React不会重新渲染,因此您可能需要在验证提交后找出一种导航的方法。

如果合适,另一个类似didSubmit的标志将允许您提供代码路径来呈现<Redirect>而不是调用navigation.push()

但是,否则,使用您当前的设置,可以允许您在进入新表单时进行导航(您的用户尚未做出任何努力),如果表单为“脏”,导航将被中断,并且导航将发生设置didSubmit后自动在下一个渲染器上显示。

const [isDirty,setIsDirty] = React.useState(false)
const [didSubmit,setDidSubmit] = React.useState(false)
const onSubmit = async (formData) => {
  try {
    await axios.post('url',formData)
    setIsDirty(false)
    setDidSubmit(true)
  } catch (error) {
    // handle your errors
  }
}
React.useEffect(() => {
  if(!isDirty) setIsDirty(true)
},[formData])
React.useEffect(() => {
  if(didSubmit) navigation.push({ ... })
},[didSubmit]

return (
  // the form...
  <Prompt when={isDirty} {...} />
)
,

当表单的输入字段发生如下所示的更改时,我已将状态isDirtyleave更新为true

render (
<Form onSubmit={handleSubmit(onSubmit)}>
   <Form.Row>
       <Form.Group as={Col} className="mr-5">
       <Form.Label column>Product Name</Form.Label>
       <Form.Control
            name="productName"
            placeholder="Enter product Name"
            required
            onChange={() => setIsDirty(true)} {/* I have updated here*/}
            ref={register}
            />
       </Form.Group>
   </Form.Row>
   <Button variant="success" type="submit" className="text-white mt-5">
            Add New Product
   </Button>
</Form>

<Prompt when={isDirty} message="Are you sure you want to leave ?" /> 
);

现在在onSubmit函数内部,在导航到目标位置之前,我已将isDirty状态更新为false。

const onSubmit = (formData) => {
    axios.post("http://localhost:4000/products",formData);
    setIsDirty(false);   //here I am setting this true
    navigation.push({
        pathname: "/productList",state: { added: "pass" },});
};

我想在这里分享一个重要的观点,即只要输入在任何时候发生变化,那么在提交表单时(在填写所有输入字段时,都只有isDirty状态为true )将状态更改为false,以便它可以导航到另一个URL。

,

在 reactjs 的功能组件中,我使用了下面的东西。这对我有用。在我离开当前页面的情况下,我想删除一些商店数据。在那种情况下,我使用了下面的东西。

useEffect(() => {
  return () => {
       // you can add your functionality here  
   };
 },[]);