RemixJS 2 action 函式
loader()
的功能是在以 GET 拜訪時,於後端執行,通常是取得頁面要使用的資料。action()
則是用來處理 GET 方法以外的要求。
實作 API
在沒有頁面的 component function,action() 和 loader() 可以用來建立 RESTful API。以下是個刪除功能的例子。
// app/modules/mysql-connect.ts // 用以建立資料庫連線
import mysql, { PoolOptions } from "mysql2/promise";
const options: PoolOptions = {
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0,
enableKeepAlive: true,
keepAliveInitialDelay: 0,
};
const pool = mysql.createPool(options);
export default pool;
// app/routes/address-book.delete.$sid.tsx
import { type ActionFunctionArgs } from "@remix-run/node";
import db from "./../modules/mysql-connect";
export async function action({ request, params }: ActionFunctionArgs) {
const output = {
success: false,
result: {},
};
const sid = params.sid;
if (request.method === "DELETE") {
if (sid && parseInt(sid)) {
const sql = `DELETE FROM address_book WHERE sid=${sid}`;
const [result] = await db.query(sql);
output.result = result;
output.success = true;
}
}
return output;
}
搭配頁面表單使用
action() 可以搭配頁面內的表單 (使用 Form 元件) 做回應,在一般情況下是以 AJAX 的方式溝通。以下是一個範例的部份程式碼。
import type { LoaderFunctionArgs, ActionFunctionArgs } from "@remix-run/node";
import {
useLoaderData,
Form,
useActionData,
} from "@remix-run/react";
import { getBodyObject } from "~/modules/handle-request-data";
export async function loader({ request, params }: LoaderFunctionArgs) {
// 載入資料
}
export default function AddressBookEdit() {
const data = useLoaderData();
const actionData = useActionData<typeof action>();
// ...
return (
<div className="container">
<Form method="post" encType="multipart/form-data">
<div className="mb-3">
<label htmlFor="email" className="form-label">
email
</label>
<input
type="text"
className="form-control"
id="email"
name="email"
value={form.email}
onChange={handleFieldChange}
/>
</div>
<button type="submit" className="btn btn-primary">
修改
</button>
</Form>
</div>
);
}
export async function action({ request, params }: ActionFunctionArgs) {
const sid = params.sid;
const body = await getBodyObject(request);
const { name, email, mobile, birthday, address } = body;
const output = {
success: false,
result: {},
bodyData: body,
};
// 變更資料
return output;
}
注意幾個要點:
- 表單必須使用
@remix-run/react
的Form
元件建立。 - 和一般表單一樣可以使用 encType 屬性決定送出的資料編碼方式。
- 可以使用 action 屬性設定表單傳送的對象 (可以不是該頁面的
action()
函式)。 - 在頁面內使用 useActionData() 取得表單送出後回傳的訊息或資料。
- 若要實作 RESTful API 可以依
request.method
是 POST、PUT 或 DELETE 來做不同的處理。
沒有留言:
張貼留言