2023-10-22

RemixJS 2 action 函式

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; }

注意幾個要點:

  1. 表單必須使用 @remix-run/reactForm 元件建立。
  2. 和一般表單一樣可以使用 encType 屬性決定送出的資料編碼方式。
  3. 可以使用 action 屬性設定表單傳送的對象 (可以不是該頁面的 action() 函式)。
  4. 在頁面內使用 useActionData() 取得表單送出後回傳的訊息或資料。
  5. 若要實作 RESTful API 可以依 request.method 是 POST、PUT 或 DELETE 來做不同的處理。

沒有留言:

FB 留言