如何将数据从 ActionFunction 传递到 Remix.run 中的 Loader 函数?

How to pass data from ActionFunction to Loader function in Remix.run?

我正在 Remix.run 申请。它由用户填写表格并最终获得成功屏幕的多个步骤组成。所有表单步骤都位于一条路线上,但成功是在它自己的路线上。

一切如何运作

我在服务器上有类似 redux 的(实际上是 XState,但并不重要)消息处理。它从字段接收当前(或初始加载的初始)状态、消息类型和数据。然后它 returns 客户端的新状态和基于该状态呈现的页面。服务器没有任何存储,我不想介绍一个,因为它会使事情复杂化。

// form page
export async function loader() {
  return json(await getInitialState())
}

export async function action({request}) {
  let fd = await request.formData();
  let {current_state, message_type, ...data} = Object.fromEntries(fd.entries());
  return json(await getNextState(current_state, {type: message_type, data}));
}

export function unstable_shouldReload({submission}) {
  return !submission
}

export default FormPage() {
  let loaderData = useLoaderData();
  let actionData = useActionData();
  // awful, isn't it?
  let currentState = actionData || loaderData;
}

我的问题

首先,我的问题是每次提交表单时都会触发加载程序。因此,ActionFunction returns 新状态,但 LoaderFunction returns 初始状态。这会很好,但是要获得初始状态,loader 运行s API,所以这是浪费的调用。我用 unstable_ShouldReload 解决了它,还可以,但不是真的。

现在我到了表单的最后一步,我觉得我有同样的问题,但现在我有单独的路线,所以我不能只阻止 运行ning LoaderFunction。我需要 LoaderFunction 在新页面上实际 运行,并获取从前面的步骤传递给它的数据。基本上,这是同样的问题 - 我需要使用以加载程序内部可用的形式发布的数据。

我尝试用所有数据替换上面使用会话 cookie 的代码,但我还有其他问题。带有会话数据的操作 returns cookie,加载程序读取它和 returns 新状态。不幸的是,它在少数情况下会失败。如果有当前会话,用户可以重新加载页面,防止再次发送信息并在发送数据时获得结果。这不是网络“通常”的工作方式。我可以通过在每次加载时销毁会话来更改它,但是如果用户端没有 JS,那么第一个 POST 请求不会产生任何结果。否则这是最好的解决方案(但受 cookie 大小的限制)。

问题

如何将上一个操作的数据传递给下一个加载程序,或在加载程序本身中处理 POST 请求?

How to pass data from last action to next loader

唯一的方法是使用会话和/或 cookie。如果您只想读取一次会话数据并确保它在重新加载后不再存在,您可以使用 session.flash(key, value),然后在您的加载程序中,当您执行 session.get(key) 时,它将删除闪存密钥从会话中,如果您在加载程序中提交会话,则 cookie 将更新为不再具有该密钥,重新加载后它将不存在。

process POST request in loader itself

这是不可能的,加载程序函数仅处理 GET 和 OPTIONS 请求,对于其他所有请求方法,仅使用操作函数。