在 remixjs 中提交时隐藏模式表单

问题描述 投票:0回答:4

我现在正在做一个混音项目,我有一个看起来像这样的文件。

import { Button, Modal } from "flowbite-react";

import {useReducer} from "react";

export const loader = ({params, request}) => {
    // a bunch of stuff here;
}
export const action = ({request}) => {
    // a bunch of stuff here;
}

const MainComponent = () => {
    
    const initialState = {
        isDeleteModalOpen = false;
    }
    
    const reducer = (state, action) => {
        const obj = Object.assign({}, state);
        
        switch (action.type){
            case "showDeleteModal":{
                obj.isDeleteModalOpen = true;
                return obj;
            }
            case "hideDeleteModal":{
                obj.isDeleteModalOpen = false;
                return obj;
            }
        }
    }
    const [state, dispatch] = useReducer(reducer, initialState);
    return (

        <>
            <button onClick={() => dispatch({type:"showDeleteModal"})}
            <React.Fragment>
                <Modal
                    show={isDeleteModalOpen}
                    onClose={() => dispatch({ type: "hideDeleteModal", id: "" })}
                    size="sm"
                    >
                    <Form method="post">
                        <Modal.Header>Are you sure?</Modal.Header>
                        <Modal.Body>
                            <div className="space-y-6">
                                <Alert color="failure" icon={HiInformationCircle}>
                                    <span>
                                        <span className="font-medium">Proceed with care! </span>{" "}
                                        This action could cause permanent data loss{" "}
                                    </span>
                                </Alert>
                            </div>
                        </Modal.Body>
                        <Modal.Footer>
                            <Button color="warning" type="submit">
                                Delete
                            </Button>

                            <Button
                                color="gray"
                                onClick={() => dispatch({ type: "hideDeleteModal" })}
                                >
                                Cancel
                            </Button>
                        </Modal.Footer>
                    </Form>
                </Modal>
            </React.Fragment>
        </>
    )

}

export default MainComponent;

模式由国家控制,现在我可以使表格正常工作。然而,提交后它就留在那里,因为我从来没有告诉它隐藏。虽然我实际上想要的是表单在用户提交时消失。不幸的是,在

useEffect
钩子内这样做似乎是不可能的。

我对此进行了多项研究,但似乎我找不到任何涵盖类似情况的解决方案。

如有任何帮助,我们将不胜感激。谢谢你。

modal-dialog remix
4个回答
0
投票

基于

fetcher.data
关闭模态。 如果
fetcher data
在那里,那么您的表单操作成功,您现在可以关闭模态,如果没有
data
变为
null
您可以显示相应的 UI。


0
投票

我最近遇到了同样的问题,以下是我如何处理它的示例,因为它适用于您的代码示例。

import { Form, useFetcher } from "@remix-run/react"
import { Alert, Button, Modal } from "flowbite-react"
import React, { useState } from "react"
import { HiInformationCircle } from "react-icons/hi"

export const loader = ({ params, request }) => {
  // a bunch of stuff here;
}
export const action = ({ request }) => {
  // a bunch of stuff here;
}

const MainComponent = () => {
  const fetcher = useFetcher()
  const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false)

  return (
    <>
      <button onClick={() => setIsDeleteModalOpen(true)} />
      <Modal
        show={isDeleteModalOpen}
        onClose={() => setIsDeleteModalOpen(false)}
        size="sm">
        <Form method="post">
          <Modal.Header>Are you sure?</Modal.Header>
          <Modal.Body>
            <div className="space-y-6">
              <Alert
                color="failure"
                icon={HiInformationCircle}>
                <span>
                  <span className="font-medium">Proceed with care! </span> This action could cause
                  permanent data loss{" "}
                </span>
              </Alert>
            </div>
          </Modal.Body>
          <Modal.Footer>
            <Button
              color="warning"
              type="button" // <- Important bit - Could not get a working solution as "submit"
              onClick={(e) => {
                setIsDeleteModalOpen(false) // <- Order of ops in onClick is Important
                fetcher.submit(e.currentTarget) // <- Use fetcher to submit
              }}>
              Delete
            </Button>

            <Button
              color="gray"
              type="button"
              onClick={() => setIsDeleteModalOpen(false)}>
              Cancel
            </Button>
          </Modal.Footer>
        </Form>
      </Modal>
    </>
  )
}

export default MainComponent

这确实删除了减速器,因为不需要它来实现所要求的目标。我假设它只是为了处理主题案例。显然,如果它在其他地方使用,您仍然可以保留它来处理任何其他现有功能。


0
投票

另一种方法是使用 Form 组件中的 reloadDocument 属性

<Form method="POST" className="flex gap-2" reloadDocument>
        <Input
          step="any"
          type="number"
          name={modal?.nameInput}
          className="flex-1"
        />
        <Button className="flex-1" type="submit">
          Save
        </Button>
</Form>

它强制进行完整的文档导航,这将关闭模式。 文档链接: https://remix.run/docs/en/main/components/form#reloaddocument


0
投票

您甚至不需要

useReducer()
,您可以使用 remix
useNavigation()
useActionData()
钩子的组合来导出您想要的状态。

如果您想在操作响应之前显示模态框,您可以使用

navigation
显示待处理状态,并使用
actionData
有效关闭模态框

const Component = () => {
  const data = useActionData()
  const navigation = useNavigation()

  // you can check if your action respond correctly here
  // here ok is a boolean returned by my action
  const isOpen = !data?.ok
  const isLoading = navigation.state !== 'submitting'

  return <Modal loading={isLoading} show={isOpen} />
}
© www.soinside.com 2019 - 2024. All rights reserved.