HTTP コンテクスト
@lazarv/react-server
を使用すると、サーバーサイドレンダリングのコンテクストに関連するすべてにアクセスできます。このガイドでは、HTTPコンテクストにアクセスする方法について説明します。
これから紹介するものは、HTTPコンテクストにアクセスして操作するためのフックまたは関数です。
これらの関数はすべて、ミドルウェアやファイルシステムベースのルーターを使用したルートハンドラーでも利用可能です。これらはフレームワーク固有であり、Reactとは関係ありません。
useHttpContext()
を使用すると、完全なHTTPコンテクストにアクセスできます。
import { useHttpContext } from "@lazarv/react-server";
export default function MyComponent() {
const context = useHttpContext();
return (
<div>
<p>Method: {context.request.method}</p>
<p>URL: {context.request.url.toString()}</p>
<p>Request Headers: {JSON.stringify(context.request.headers)}</p>
<p>Request Cookies: {JSON.stringify(context.request.cookie)}</p>
</div>
);
};
useRequest()
を使用すると、完全なHTTPリクエストにアクセスできます。
import { useRequest } from "@lazarv/react-server";
export default function MyComponent() {
const request = useRequest();
return (
<div>
<p>Method: {request.method}</p>
<p>URL: {request.url.toString()}</p>
<p>Headers: {JSON.stringify(request.headers)}</p>
<p>Cookies: {JSON.stringify(request.cookie)}</p>
</div>
);
};
useResponse()
を使用すると、完全なHTTPレスポンスにアクセスできます。これは、レスポンスがクライアントに送信された後、サスペンドされ、後でクライアントにストリーミングされたReactコンポーネント内でのみ利用可能です。
import { useResponse } from "@lazarv/react-server";
export default function MyComponent() {
const response = useResponse();
return (
<div>
<p>Headers: {JSON.stringify(response.headers)}</p>
<p>Cookies: {JSON.stringify(response.cookie)}</p>
</div>
);
};
useUrl()
を使用すると、現在のリクエストのURLにアクセスできます。
import { useUrl } from "@lazarv/react-server";
export default function MyComponent() {
const url = useUrl();
return <p>URL: {url.href}</p>;
};
usePathname()
を使用すると、現在のリクエストのパス名にアクセスできます。
import { usePathname } from "@lazarv/react-server";
export default function MyComponent() {
const pathname = usePathname();
return <p>Pathname: {pathname}</p>;
};
useSearchParams()
を使用すると、現在のリクエストの検索パラメータにアクセスできます。これは、検索パラメータのキーと値のペアを持つオブジェクトです。同じキーに複数の値がある場合、その値は配列になります。
import { useSearchParams } from "@lazarv/react-server";
export default function MyComponent() {
const searchParams = useSearchParams();
return (
<p>Search params: {JSON.stringify(searchParams)}</p>
);
};
headers()
を使用すると、現在のリクエストのヘッダーにアクセスできます。
import { headers } from "@lazarv/react-server";
export default function MyComponent() {
const requestHeaders = headers();
return <p>Headers: {JSON.stringify(requestHeaders)}</p>;
};
キーと値のペアのオブジェクトを渡すことで、現在のレスポンスのヘッダーを変更することもできます。
import { headers } from "@lazarv/react-server";
export default function MyComponent() {
headers({
"X-My-Header": "My value",
});
return <p>Headers: {JSON.stringify(headers())}</p>;
};
または、Headers
オブジェクトを渡すことでも変更できます。
import { headers } from "@lazarv/react-server";
export default function MyComponent() {
headers(new Headers({
"X-My-Header": "My value",
}));
return <p>Headers: {JSON.stringify(headers())}</p>;
};
または、キーと値のペアの配列を渡すことでも変更できます。
import { headers } from "@lazarv/react-server";
export default function MyComponent() {
headers([
["X-My-Header", "My value"],
]);
return <p>Headers: {JSON.stringify(headers())}</p>;
};
headers()
関数を使用してヘッダーを変更すると、現在のレスポンスのヘッダーが上書きされます。レスポンスヘッダーを直接変更したい場合は、ヘッダーを設定、追加、削除するための3つの補助関数を使用できます。これらの関数は setHeader()
、appendHeader()
、および deleteHeader()
です。
import { setHeader, appendHeader, deleteHeader } from "@lazarv/react-server";
export default function MyComponent() {
setHeader("X-My-Header", "My first value");
appendHeader("X-My-Header", "My second value");
deleteHeader("X-My-Header");
return <p>Check the response headers!</p>;
}
注意: HTTPヘッダーは大文字と小文字を区別しないことに注意してください!
cookie()
を使用すると、現在のリクエストのクッキーにアクセスできます。
import { cookie } from "@lazarv/react-server";
export default function MyComponent() {
const requestCookies = cookie();
return <p>Cookies: {JSON.stringify(requestCookies)}</p>;
};
また、現在のレスポンスのコンテクストでクッキーを設定または削除することもできます。
import { setCookie, deleteCookie } from "@lazarv/react-server";
export default function MyComponent() {
setCookie("my-cookie", "my-value");
deleteCookie("other-cookie");
return <p>Cookies: {JSON.stringify(cookie())}</p>;
};
status()
を使用すると、現在のレスポンスのステータスコードとテキストを設定できます。
import { status } from "@lazarv/react-server";
export default function MyComponent() {
status(404, "Not found");
return <p>Not Found</p>;
};
useFormData()
を使用すると、現在のリクエストのフォームデータにアクセスできます。
import { useFormData } from "@lazarv/react-server";
export default function MyComponent() {
const formData = useFormData();
return (
<p>Form data: {JSON.stringify(Object.fromEntries(formData.entries()))}</p>
);
};
redirect()
を使用すると、現在のリクエストを別のURLにリダイレクトできます。
警告:
redirect()
関数はエラーをスローし、フレームワークがそれをキャッチしてリダイレクトを実行します。try
/catch
ブロック内でredirect()
を使用する場合、リダイレクトエラーであれば再スローすることを確認してください。
import { redirect } from "@lazarv/react-server";
export default function MyComponent() {
redirect("https://example.com");
};
rewrite()
を使用すると、現在のリクエストを別のURLにリライトできます。これは、ミドルウェア関数内で現在のリクエストのURLパス名を変更するのに便利です。
import { rewrite, useUrl } from "@lazarv/react-server";
export function init$() {
return async () => {
const { pathname } = useUrl();
if (pathname === "/old-pathname") {
rewrite("/new-pathname");
}
};
}
export default function MyComponent() {
const { pathname } = useUrl();
return <p>Current pathname: {pathname}</p>;
}
useOutlet()
を使用すると、現在のリクエストのアウトレットにアクセスできます。これは、現在のリクエストがレンダリングされているアウトレットの名前を取得するのに便利です。
import { useOutlet } from "@lazarv/react-server";
export default function MyComponent() {
const outlet = useOutlet();
return <p>Outlet: {outlet}</p>;
}
useRender()
を使用すると、現在のリクエストのレンダーロックにアクセスできます。これは、非同期関数が実行されている間、またはロックが解除されるまで、React Server Componentのレンダリングをロックしたい場合に便利です。なぜならReact Server Componentはデフォルトでストリーミングを使用してレンダリングされるからです。特にHTTPヘッダーやクッキーを非同期のReact Server Componentで処理する場合に役立ちます。レンダリングをロックしないと、非同期関数が終了する前にヘッダーやクッキーがクライアントに送信されてしまいます。レンダリングプロセスでロックが検出されると、レンダリングはロックが解除されるまで待機し、ヘッダーやクッキーの送信を開始してからReact Server Componentのストリーミングを開始します。
import { headers, useRender } from "@lazarv/react-server";
export default function MyComponent() {
const { lock } = useRender();
await lock(async () => {
// Do something async
await new Promise((resolve) => setTimeout(resolve, 1000));
headers({
"x-lock": "works",
});
});
return <p>Render lock</p>;
}
lock()
関数を使用して、後でロックを解除するための unlock()
関数を取得することもできます。
import { headers, useRender } from "@lazarv/react-server";
export default function MyComponent() {
const { lock } = useRender();
const unlock = lock();
// Do something async
await new Promise((resolve) => setTimeout(resolve, 1000));
headers({
"x-lock": "works",
});
unlock();
return <p>Render lock</p>;
}