全书目录

第三十一篇:Remix 完全指南 —— Web 原生航运港宇宙

十三、`Form` 和 `fetcher` 的区别:主航线 vs 旁路作业通道

1 分钟 332 字 第 576 / 962 个阅读单元

这一点非常关键,几乎是 Remix 使用熟练度的分水岭。

#<Form> 的场景

当这次提交会影响:

  • 当前 URL
  • 浏览器历史记录
  • 页面级导航
  • 提交成功后用户应该“到另一站”或“把这一站当成新状态”

比如:

  • 登录
  • 创建记录后跳详情页
  • 搜索筛选并把条件放进 URL
  • 编辑完成后返回详情页

#useFetcher() 的场景

当你只是想做一个“局部操作”,不想改主航线:

  • 列表项点赞
  • 切换收藏
  • 表格里单行删除
  • 弹窗内局部提交
  • 自动补全建议
  • 局部加载更多

示例:

tsx
import { useFetcher } from "@remix-run/react";

function FavoriteButton({ shipId, isFavorite }: { shipId: string; isFavorite: boolean }) {
  const fetcher = useFetcher();

  const optimisticFavorite =
    fetcher.formData?.get("favorite") === "true" ? true :
    fetcher.formData?.get("favorite") === "false" ? false :
    isFavorite;

  return (
    <fetcher.Form method="post" action={`/ships/${shipId}/favorite`}>
      <button
        type="submit"
        name="favorite"
        value={optimisticFavorite ? "false" : "true"}
      >
        {optimisticFavorite ? "取消重点关注" : "设为重点关注"}
      </button>
    </fetcher.Form>
  );
}

这个交互的味道很像:

  • 主船还停在当前泊位
  • 旁边开一个快速作业通道
  • 只处理这一个小货柜
  • 不要整条航线改道

一句话记:

会不会换页面、改 URL、进历史栈? 会,优先 Form。 不会,优先 fetcher