我现在正在做一个混音项目,我有一个看起来像这样的文件。
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
钩子内这样做似乎是不可能的。
我对此进行了多项研究,但似乎我找不到任何涵盖类似情况的解决方案。
如有任何帮助,我们将不胜感激。谢谢你。
基于
fetcher.data
关闭模态。
如果 fetcher data
在那里,那么您的表单操作成功,您现在可以关闭模态,如果没有 data
变为 null
您可以显示相应的 UI。
我最近遇到了同样的问题,以下是我如何处理它的示例,因为它适用于您的代码示例。
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
这确实删除了减速器,因为不需要它来实现所要求的目标。我假设它只是为了处理主题案例。显然,如果它在其他地方使用,您仍然可以保留它来处理任何其他现有功能。
另一种方法是使用 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
您甚至不需要
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} />
}