[英]Confirmation message before saving data in remix js
我的saveData.tsx
Remix 應用程序中有一個Action
function,它將一些數據保存在數據庫表中。 這是文件
import type { ActionArgs } from "@remix-run/node";
import { redirect } from "@remix-run/node";
import { Form, useActionData } from "@remix-run/react";
import React from "react";
import { saveData } from "~/models/data.server";
export const action = async ({ request, params }: ActionArgs) => {
// do some work, collect the `result` which is a JSON.. and then
await saveData(result);
return redirect (`/to/saveData`);
}
export default function Index() {
const actionData = useActionData<typeof action>();
return(
<div>
<Form method="post">
<button type="submit">Upload data</button>
</Form>
</div>
);
}
所以我真正想做的是,我想在await saveData(result)
之前收到一條確認消息。 我將確認消息設置為另一個帶有兩個按鈕Save
或Cancel
的tsx
文件。 模態在不同的路線上。 例如(/to/confirm.tsx)
。 我想在保存await saveData(result)
之前調用此confirm.tsx
。 然后,當我單擊confirm.tsx
中的“ Save
”按鈕時,我想運行await saveData(result)
並將數據保存到數據庫。 反之亦然,當我單擊cancel
時,我想取消數據保存並redirect
到saveData.tsx
。
我沒有在confirm.tsx
中使用任何Action
或Loader
函數。 這是confirm.tsx
文件
export default function Confirm() {
return (
<div>
<div>
<h1>Are you sure you want to save the data?</h1>
</div>
<div>
<button>Save</button>
</div>
<div>
<button>Cancel</button>
</div>
</div>
)
}
我最初做的是,我將result
作為字符串傳遞給URL
,而沒有在 saveData.tsx 的Action
function 中使用await saveData(result)
saveData.tsx
export const action = async ({ request, params }: ActionArgs) => {
// do some work, collect the `result` which is a JSON.. and then
// await saveData(result); <= did not used save functioin inside this file
return redirect(`/to/${JSON.stringify(result)}/confirm`)
}
我以前使用confirm.tsx
路由/to/$data/confirm
然后在confirm.tsx
中,我使用了一個Action
function。在那個Action
function 中,我使用params
得到了jsonString
。 然后JSON.pares
編輯jsonString
並將 object 傳遞給await saveData(jsonParsedData)
。 然后在保存數據后,重定向到之前的路由saveData.tsx
,如下所示。
import type { ActionArgs } from "@remix-run/node";
import { redirect } from "@remix-run/node";
import { Form, useActionData } from "@remix-run/react";
import React from "react";
import { saveData } from "~/models/data.server";
export const action = async ({ request, params }: ActionArgs) => {
const jsonString = params.data;
const jsonParsedData = JSON.parse(jsonString);
await saveData(jsonParsedData);
return redirect(`/to/saveData`);
}
export default function Confirm() {
return (
<div>
<div>
<h1>Are you sure you want to save the data?</h1>
</div>
<div>
<Form method="post">
<button>Save</button>
</Form>
</div>
<div>
<Link to={`/to/saveData`}>
<button>Cancel</button>
</Link>
</div>
</div>
)
}
以前的方法有效。 但是以這種方式處理成千上萬的數據是不可能的(將數據傳遞到 URL)。 我只需要在一個文件中完成所有過程,而不需要將數據傳遞到另一個文件中。 我只想使用不同的componant
或文件或其他任何東西來控制數據保存確認。
我想我已經清楚地解釋了這個問題,如果不清楚請告訴我如何幫助它進一步解釋。 在這個問題上的幫助將不勝感激..
如果本機警報對您來說不夠 Window.confirm() (我強烈推薦)
if (window.confirm("Do you really want to save?")) {
run this if user say yes
}
您可以將模態組件導入頁面並有條件地顯示它
例如,觸發action
的元素更改為 state:
const [showConfirmationModal, setShowConfirmationModal] = useState(false)
然后你有條件地渲染它
{ showConfirmationModal && <confirmModal confirmCallback={action}></confirmModal> }
或者你可以通過作為道具來展示
<confirmModal show={showConfirmationModal} confirmCallback={action}>
action
function 是異步代碼。 您不能在action
處理程序中間停止並呈現任何 React 組件。 我懷疑你需要做的是:
action
,並將數據返回給組件。Index
組件將跟蹤表單何時提交,以便在返回數據時組件可以觸發確認模式,處理用戶響應,然后發出命令式重定向。它可能類似於以下內容:
import React from "react";
import type { ActionArgs } from "@remix-run/node";
import { redirect } from "@remix-run/node";
import { Form, useActionData, useTransition } from "@remix-run/react";
import { useNavigate } from "react-router-dom";
import { saveData } from "~/models/data.server";
export const action = async ({ request, params }: ActionArgs) => {
// do some work, collect the `result`, and then
return /* JSON data */
}
export default function Index() {
const data = useActionData<typeof action>();
const navigate = useNavigate();
const transition = useTransition();
const [submitted, setSubmitted] = React.useState(false);
const [showConfirmSave, setShowConfirmSave] = React.useState(false);
React.useEffect(() => {
switch(transition.state) {
case "submitting":
if (!submitted) {
setSubmitted(true);
}
break:
case "idle":
if (submitted && data) {
setShowConfirmSave(true);
}
break:
}
}, [data, submitted, setShowConfirmSave, setSubmitted, transition]);
const confirmHandler = async () => {
await saveData(result);
navigate("/to/saveData");
};
if (showConfirmSave) {
return <Confirm onConfirm={confirmHandler} />
}
return(
<div>
<Form method="post">
<button type="submit">Upload data</button>
</Form>
</div>
);
}
import React from "react";
interface ConfirmProps {
onConfirm: () => void;
}
export default function Confirm({ onConfirm }: ConfirmProps) {
return (
<div>
<div>
<h1>Are you sure you want to save the data?</h1>
</div>
<div>
<button type="button" onClick={onConfirm}>Save</button>
</div>
<div>
<Link to="/to/saveData">
<button type="button">Cancel</button>
</Link>
</div>
</div>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.