如何点击Delete按钮传递ID?Remix+Shopify Admin REST API技术问题
问题:Remix中点击按钮传递主题ID调用Shopify Admin API删除Asset
我是新手,希望在Shopify Admin REST API的Asset操作示例中加入动态id。由于所有REST Admin API请求都需要有效的Shopify访问令牌,所有示例必须在headers、action和loader函数内实现。
我编写了如下Remix代码示例:
export const loader = async ( { request, params } ) => { const { admin, session } = await authenticate.admin( request ); const data = await admin.rest.resources.Asset.all({ session: session, theme_id: params.id, // Pass id here asset: {"key": "sections/header.liquid"} }); return json( { data } ); } const App = () => { const { data } = useLoaderData(); console.log( data ); return ( // Is there any way without using Form and useActionData? <button id="136012988610" onClick={ /* Pass this button id when click */ }>Delete section from this theme</button> ); }; export default App;
需求说明
点击Delete按钮时,需要传递按钮上的主题ID,调用Shopify API执行删除Asset的操作,希望找到可行的实现方式,最好能不用Form和useActionData。
相关参考
- 选择要删除的主题ID:

- 传递主题ID的API文档说明:

解决方案
方法1:使用Fetch调用Remix Action(推荐,符合Remix架构)
Remix中处理数据修改(比如删除)推荐用action函数,你可以通过fetch在点击事件中调用action,传递主题ID:
- 添加
action函数处理删除逻辑:
export const action = async ({ request }) => { const formData = await request.formData(); const themeId = formData.get("themeId"); const assetKey = "sections/header.liquid"; // 可根据需求动态传递 const { admin, session } = await authenticate.admin(request); try { await admin.rest.resources.Asset.delete({ session: session, theme_id: themeId, asset: { key: assetKey } }); return json({ success: true }); } catch (error) { return json({ success: false, error: error.message }, { status: 400 }); } };
- 修改组件中的点击事件:
const App = () => { const { data } = useLoaderData(); const handleDelete = async (e) => { const themeId = e.target.id; const formData = new FormData(); formData.append("themeId", themeId); const response = await fetch("/your-route-path", { // 替换为你的实际路由路径 method: "POST", body: formData, headers: { "X-Requested-With": "XMLHttpRequest" } }); const result = await response.json(); if (result.success) { console.log("删除成功"); // 可在此更新UI,比如重新加载数据 window.location.reload(); } else { console.error("删除失败", result.error); } }; return ( <button id="136012988610" onClick={handleDelete}>Delete section from this theme</button> ); }; export default App;
方法2:结合useRevalidator实现无刷新更新
如果需要无刷新更新页面数据,可以搭配Remix的useRevalidator:
import { useRevalidator } from "@remix-run/react"; const App = () => { const { data } = useLoaderData(); const { revalidate } = useRevalidator(); const handleDelete = async (e) => { const themeId = e.target.id; const formData = new FormData(); formData.append("themeId", themeId); const response = await fetch("/your-route-path", { method: "POST", body: formData }); if (response.ok) { revalidate(); // 重新调用loader更新页面数据 } }; return ( <button id="136012988610" onClick={handleDelete}>Delete section from this theme</button> ); };
方法3:跳过Form和useActionData的直接Fetch调用(不推荐)
如果坚持不用Form和useActionData,可以直接在前端调用Shopify API,但需注意令牌安全:
const handleDelete = async (e) => { const themeId = e.target.id; const assetKey = "sections/header.liquid"; // 注意:令牌需从服务器端传递到前端,禁止硬编码 const accessToken = data.accessToken; // 从loader返回的data中获取 const shopDomain = "your-shop-domain.myshopify.com"; try { const response = await fetch(`https://${shopDomain}/admin/api/2024-04/themes/${themeId}/assets.json`, { method: "DELETE", headers: { "X-Shopify-Access-Token": accessToken, "Content-Type": "application/json" }, body: JSON.stringify({ asset: { key: assetKey } }) }); if (response.ok) { console.log("删除成功"); } else { const error = await response.json(); console.error("删除失败", error); } } catch (error) { console.error("请求出错", error); } };
警告:直接在前端暴露Shopify访问令牌存在安全风险,强烈推荐通过Remix的action函数代理请求,令牌仅在服务器端使用。
内容的提问来源于stack exchange,提问作者ttn_
相关产品推荐
相关产品推荐

