Open9

Remixまわり備忘

bisquit_devbisquit_dev

fetcher.loadとfetcher.submitの違いは?

fetcher.load → loaderが呼ばれる
fetcher.submit → method = getならloaderが呼ばれる。get以外ならactionが呼ばれる

Any form submissions that are "post" will call your data "action". Any "get" submissions (<Form method="get">) will be handled by your "loader".

https://remix.run/docs/en/v1/guides/data-writes#:~:text=Any form submissions that are "post" will call your data "action". Any "get" submissions (<Form method%3D"get">) will be handled by your "loader".

If a non-GET request is made to your route (POST, PUT, PATCH, DELETE) then the action is called before the loaders.

https://remix.run/docs/en/v1/route/action#:~:text=If a non-GET request is made to your route (POST%2C PUT%2C PATCH%2C DELETE) then the action is called before the loaders.

じゃあfetcher.loadfetcher.submit(method = get)の違いは?

bisquit_devbisquit_dev

sergiodxa — 2022/11/04 01:07
fetcher.load to send a GET request to a URL
fetcher.submit to send both GET or POST to a URL but attaching user data

bisquit_devbisquit_dev

実験

fetcher.load('/data/some')
-> revalidationは起きない

fetcher.submit(null, { action: '/data/some' }
fetcher.submit(null, { action: '/data/some', method: 'get' }
-> revalidationは起きない

fetcher.submit(null, { action: '/data/some', method: 'post' }
fetcher.submit(null, { action: '/data/some', method: 'put' }
fetcher.submit(null, { action: '/data/some', method: 'patch' }
fetcher.submit(null, { action: '/data/some', method: 'delete' }
-> revalidationは起きる

bisquit_devbisquit_dev

実験

fetcher.load('/data/null?foo=bar');

export async function loader({ request, params }: LoaderArgs) {
  console.log('loader', request.url);
  // http://localhost:3100/data/null?foo=bar
  return null;
}

fetcher.submit({ foo: 'bar' }, { action: '/data/null', method: 'get' })

export async function loader({ request, params }: LoaderArgs) {
  console.log('loader', request.url);
  // http://localhost:3100/data/null?foo=bar
  return null;
}

同じ結果

bisquit_devbisquit_dev

つまり、以下は全く同じ

  • fetcher.load('/data/null?foo=bar')
  • fetcher.submit({ foo: 'bar' }, { action: '/data/null', method: 'get' })

どちらも、

  • Routeのloaderが呼ばれる
    • submitの場合でもデータがクエリ文字列として連結される e.g. /data/null?foo=bar
    • よってデータはSearchParameterとして受け取る
  • revalidationをトリガーしない
bisquit_devbisquit_dev

fetcher.loadが遷移時に呼ばれる

fetcher.loadは任意のRouteの非同期的な読み込みなので、Routeの再描画トリガーと同じ以下のタイミングでリロードされる(多分)。

  • action実行後(form, fetcher.submit等)
  • URL search parameter変更時
  • 同じURLのリンクをクリックした時

ref. https://remix.run/docs/en/v1/guides/data-loading#remix-optimizations

たとえば検索があるような画面でキーワードを変更した時に ?keyword=hoge のようなパラメータ遷移にしている場合は上記に該当するため、たとえuseEffectなどがトリガーされなくてもfetcher.loadの読み込み先Routeがリロードされる。

もし、これがパフォーマンス劣化を起こすなら shouldRevalidate で制御する。
https://remix.run/docs/en/v1/route/should-revalidate#ignoring-search-params

パフォーマンス以前に、ループの要因になってしまっている場合は、 ループする側で変更チェックして対応する。
(shouldRevalidateはあくまでパフォーマンス改善のためにあって、その有無でバグが抑制されるべきでない)