Tanstack-Start(React) : (1)
2026年8月12日遷移
Nextjsではクライアントサイドがrouter.push()、サーバーサイドがredirect()だったが、Tanstack-startではクライアントサイドでは navigate({}) 、サーバーサイドでは throw redirect({})
// クライアントサイド
const navigate = useNavigate()
navigate({ to: '/dashboard' })
---
// サーバーサイド
if (!user) {
throw redirect({
to: '/login',
})
}throwの方はloader内で使える。
Nextjsの router.refresh()に相当するのはrouter.invalidate()
const router = useRouter();
router.invalidate();ルート
2パターンのルート定義( localhost:3000/post):Nextjsのようなフォルダベースの方がわかりやすい
/post/index.tsxpost.tsx
APIルート:
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/api/test")({
server: {
handlers: {
GET: () => {
return new Response('Hello "/api/test"!');
},
},
},
});routes/apiフォルダ内にファイルを作成する必要は必ずしも無く、handlersでHTTPメソッドを定義するとAPIルートになる。
ルートに含めないフォルダ:
_をフォルダの先頭に付ける。Nextjsのルートグループ()に相当
serverFn
export const Route = createFileRoute("/about")({
component: About,
loader: async () => {
return await getFn();
},
}); const data = Route.useLoaderData();
{data.map((item) => (
<div key={item.id}>
{item.title}
<form
action={async () => {
await deleteFn({ data: { id: item.id } });
router.invalidate();
}}
>
<button type="submit">Delete</button>
</form>
</div>
))}createServerFn():
export const getFn = createServerFn().handler(async () => {
const prisma = new PrismaClient({ adapter: new PrismaD1(env.test_db) });
return await prisma.todo.findMany();
});createServerFn()はloader:(クライアントとサーバーの両方で実行)やJSX内からも呼び出せる。
createServerOnlyFn():
export const getFn = createServerFn().handler(async () => {
return await getFn2();
});
export const getFn2 = createServerOnlyFn(async () => {
const prisma = new PrismaClient({ adapter: new PrismaD1(env.test_db) });
return await prisma.todo.findMany();
});loader:内でも直接呼び出すことは出来ないので、使い方としてはcreateServerFn()の中で呼び出す形になる。
エラー:ハッシュ化
Error: Server function info not found for 932982b246cc70164f48cc8d310fd8d30ade127
export const getSession = createServerFn({ method: "GET" }).handler(async () => {
const headers = getRequestHeaders();
const session = await auth.api.getSession({ headers });
return session;
});上記を他の
createServerFn()から呼び出すとエラーが出る。pnpm run devでは出ないが preview / deploy後に出る。原因:
createServerFn()はクライアントから呼び出されるサーバー関数として、ビルド時にクライアントとサーバーにハッシュIDが登録される。しかし、createServerFn()の中にcreateServerFn()を置くと、ビルド時にそのハッシュIDがサーバー側から消える(不整合が起こる)ため上記のようなエラーが出る。createServerFn()内で呼び出すサーバー関数はただのasync関数で良い。
-->
tanstack-start v1 でこれを試すとエラーが出なくなっていた。おそらく修正されている。
RSC
const Header = async () => {
const admin = await isAdmin();
admin && return ({
})TanstackはSSR(サーバーでHTML生成)はするがReact Server Components(RSC)は使わないので、切り分けたコンポーネント単位でNext.jsのようにサーバーで完結する処理はできない。
createServerFnはAPIに問い合わせてサーバー処理を実行するので、関数のロジックは見えないものの関数名や返り値はクライアントからわかる。
const { data } = useQuery({
queryKey: ["tags"],
queryFn: getTags,
});切り分けたコンポーネントでserverFnを使う場合は
useQueryを使う。
Tanstack-Query
queryKey
Tanstack-Query は取得したデータをブラウザのメモリに保存するが、そのデータを取り出すための「キー」として queryKey を使う。異なるコンポーネントで同じ queryKey を使えば、同じデータ(キャッシュ)を共有できる。
staleTime / gcTime
staleTime:
アプリ内でページ遷移をし、戻ってきてもfetchをしない期間の設定。
デフォルトは0なので、何かしらの数値を設定したほうが良い。
gcTime:
一度ページを離れて、もう一度画面に帰ってきたとき(再アクセス時)にどう振る舞うかの設定。gcTime内にそのサイトにアクセスすると、データがキャッシュ済みなのですぐに表示される。
デフォルトは5分で、特にここからいじる必要はない。