diff --git a/pages/docs/pagination.ja.mdx b/pages/docs/pagination.ja.mdx index 5683cb1c..844f169e 100644 --- a/pages/docs/pagination.ja.mdx +++ b/pages/docs/pagination.ja.mdx @@ -1,18 +1,18 @@ import Callout from 'nextra-theme-docs/callout' -# Pagination +# ページネーション - Please update to the latest version (≥ 0.3.0) to use this API. The previous useSWRPages API is now deprecated. + このAPIを使用するには、最新バージョン (≥ 0.3.0) に更新してください。以前の useSWRPages API は非推奨になりました。 -SWR provides a dedicated API `useSWRInfinite` to support common UI patterns such as **pagination** and **infinite loading**. +SWR は、**ページネーション**や**無限ローディング**などの一般的な UI パターンをサポートするための専用 API である useSWRInfinite を提供しています。 -## When to Use `useSWR` +## いつ `useSWR` を使用するか -### Pagination +### ページネーション -First of all, we might **NOT** need `useSWRInfinite` but can use just `useSWR` if we are building something like this: +まず第一に、`useSWRInfinite` は必要**ない**かもしれませんが、次のようなものを構築しようとするときには `useSWR` を使用できます:
@@ -38,17 +38,17 @@ First of all, we might **NOT** need `useSWRInfinite` but can use just `useSWR` i -...which is a typical pagination UI. Let's see how it can be easily implemented with -`useSWR`: +...これは典型的なページネーション UI です。`useSWR` を使って簡単に実装する方法を +みてみましょう: ```jsx highlight=5 function App () { const [pageIndex, setPageIndex] = useState(0); - // The API URL includes the page index, which is a React state. + // この API URL は、React の状態としてページのインデックスを含んでいます const { data } = useSWR(`/api/data?page=${pageIndex}`, fetcher); - // ... handle loading and error states + // ... ローディングとエラー状態を処理します return
{data.map(item =>
{item.name}
)} @@ -58,13 +58,13 @@ function App () { } ``` -Furthermore, we can create an abstraction for this "page component": +さらに、この「ページコンポーネント」を抽象化できます: ```jsx highlight=13 function Page ({ index }) { const { data } = useSWR(`/api/data?page=${index}`, fetcher); - // ... handle loading and error states + // ... ローディングとエラー状態を処理します return data.map(item =>
{item.name}
) } @@ -80,8 +80,8 @@ function App () { } ``` -Because of SWR's cache, we get the benefit to preload the next page. We render the next page inside -a hidden div, so SWR will trigger the data fetching of the next page. When the user navigates to the next page, the data is already there: +SWR のキャッシュがあるため、次のページを事前にロードできるという利点があります。次のページを非表示の div 内にレンダリングすると、 +SWR は次のページのデータフェッチを開始します。ユーザーが次のページに移動したときには、データはすでにそこにあります。 ```jsx highlight=6 function App () { @@ -96,13 +96,13 @@ function App () { } ``` -With just 1 line of code, we get a much better UX. The `useSWR` hook is so powerful, -that most scenarios are covered by it. +たった 1 行のコードで、とても優れた UX を実現できます。`useSWR` フックは非常に強力で、 +ほとんどのシナリオをカバーしています。 -### Infinite Loading +### 無限ローディング -Sometimes we want to build an **infinite loading** UI, with a "Load More" button that appends data -to the list (or done automatically when you scroll): +「さらに読み込む」ボタンを使用して(またはスクロールすると自動的に実行されて)リストにデータを +追加する**無限ローディング** UI を構築したい場合があります:
@@ -118,8 +118,8 @@ to the list (or done automatically when you scroll): -To implement this, we need to make **dynamic number of requests** on this page. React Hooks have [a couple of rules](https://reactjs.org/docs/hooks-rules.html), -so we **CANNOT** do something like this: +実装するには、このページで**動的な多くのリクエスト**を行う必要があります。 +React フックには[いくつかのルール](https://reactjs.org/docs/hooks-rules.html)があるため、次のようなことは**できません**: ```jsx highlight=5,6,7,8,9 function App () { @@ -127,7 +127,7 @@ function App () { const list = [] for (let i = 0; i < cnt; i++) { - // 🚨 This is wrong! Commonly, you can't use hooks inside a loop. + // 🚨 これは間違いです!通常、ループの中でフックは使えません const { data } = useSWR(`/api/data?page=${i}`) list.push(data) } @@ -137,12 +137,12 @@ function App () {
{ data.map(item =>
{item.name}
) }
)} - +
} ``` -Instead, we can use the `` abstraction that we created to achieve it: +代わりに、抽象化して作成した `` を使うことができます: ```jsx highlight=5,6,7 function App () { @@ -155,18 +155,18 @@ function App () { return
{pages} - +
} ``` -### Advanced Cases +### 高度なケース -However, in some advanced use cases, the solution above doesn't work. +しかし、一部の高度なユースケースでは、上記のソリューションが機能しません。 -For example, we are still implementing the same "Load More" UI, but also need to display a number -about how many items are there in total. We can't use the `` solution anymore because -the top level UI (``) needs the data inside each page: +たとえば、先ほどの「さらに読み込む」UI をまだ実装しているときに、合計でいくつのアイテムがあるかの数値も +表示する必要がでてきました。トップレベルの UI (``) が各ページ内のデータを必要とするため、 +`` を使ったソリューションは使えなくなってしまいました: ```jsx highlight=10 function App () { @@ -180,19 +180,19 @@ function App () { return

??? items

{pages} - +
} ``` -Also, if the pagination API is **cursor based**, that solution doesn't work either. Because each page -needs the data from the previous page, they're not isolated. +また、ページネーション API が**カーソルベース**の場合も、このソリューションは機能しません。 +各ページには前ページのデータが必要なため、分離されていません。 -That's how this new `useSWRInfinite` Hook can help. +ここで新しい `useSWRInfinite` フックが役立ちます。 ## useSWRInfinite -`useSWRInfinite` gives us the ability to trigger a number of requests with one Hook. This is how it looks: +`useSWRInfinite` は、一つのフックで多数のリクエストを開始する機能を提供します。このような形になります: ```jsx const { data, error, isValidating, mutate, size, setSize } = useSWRInfinite( @@ -200,38 +200,38 @@ const { data, error, isValidating, mutate, size, setSize } = useSWRInfinite( ) ``` -Similar to `useSWR`, this new Hook accepts a function that returns the request key, a fetcher function, and options. -It returns all the values that `useSWR` returns, including 2 extra values: the page size and a page size setter, like a React state. +`useSWR` と同様に、この新しいフックは、リクエストキー、フェッチャー関数、およびオプションを返す関数を受け取ります。 +これは `useSWR` が返すすべての値を返します。これらの値には、ページサイズと、React の状態のようなページサイズのセッターの二つの追加の値が含まれます。 -In infinite loading, one _page_ is one request, and our goal is to fetch multiple pages and render them. +無限ローディングでは、1 _ページ_が一つのリクエストであり、目標は複数ページをフェッチしてレンダリングすることです。 ### API -#### Parameters +#### 引数 -- `getKey`: a function that accepts the index and the previous page data, returns the key of a page -- `fetcher`: same as `useSWR`'s [fetcher function](/docs/data-fetching) -- `options`: accepts all the options that `useSWR` supports, with 3 extra options: - - `initialSize = 1`: number of pages should be loaded initially - - `revalidateAll = false`: always try to revalidate all pages - - `persistSize = false`: don't reset the page size to 1 (or `initialSize` if set) when the first page's key changes +- `getKey`: インデックスと前ページのデータを受け取る関数であり、ページのキーを返します +- `fetcher`: `useSWR` の[フェッチャー関数](/docs/data-fetching)と同じ +- `options`: `useSWR` がサポートしているすべてのオプションに加えて、三つの追加オプションを受け取ります: + - `initialSize = 1`: 最初にロードするページ数 + - `revalidateAll = false`: 常にすべてのページに対して再検証を試みる + - `persistSize = false`: 最初のページのキーが変更されたときに、ページサイズを 1 (またはセットされていれば `initialSize`)にリセットしない - Note that the `initialSize` option is not allowed to change in the lifecycle. + `initialSize` オプションはライフサイクルで変更できないことに注意してください。 -#### Return Values +#### 返り値 -- `data`: an array of fetch response values of each page -- `error`: same as `useSWR`'s `error` -- `isValidating`: same as `useSWR`'s `isValidating` -- `mutate`: same as `useSWR`'s bound mutate function but manipulates the data array -- `size`: the number of pages that _will_ be fetched and returned -- `setSize`: set the number of pages that need to be fetched +- `data`: 各ページのフェッチしたレスポンス値の配列 +- `error`: `useSWR` の `error` と同じ +- `isValidating`: `useSWR` の `isValidating` と同じ +- `mutate`: `useSWR` のバインドされたミューテート関数と同じですが、データ配列を操作します +- `size`: フェッチして返される_だろう_ページ数 +- `setSize`: フェッチする必要のあるページ数を設定します -### Example 1: Index Based Paginated API +### 例 1: インデックスにもとづいたページネーション API -For normal index based APIs: +通常のインデックスにもとづいた API の場合: ``` GET /users?page=0&limit=10 @@ -244,43 +244,43 @@ GET /users?page=0&limit=10 ``` ```jsx highlight=4,5,6,7,10 -// A function to get the SWR key of each page, -// its return value will be accepted by `fetcher`. -// If `null` is returned, the request of that page won't start. +// 各ページの SWR キーを取得する関数であり、 +// その返り値は `fetcher` に渡されます。 +// `null` が返ってきた場合は、そのページのリクエストは開始されません。 const getKey = (pageIndex, previousPageData) => { - if (previousPageData && !previousPageData.length) return null // reached the end - return `/users?page=${pageIndex}&limit=10` // SWR key + if (previousPageData && !previousPageData.length) return null // 最後に到達した + return `/users?page=${pageIndex}&limit=10` // SWR キー } function App () { const { data, size, setSize } = useSWRInfinite(getKey, fetcher) if (!data) return 'loading' - // We can now calculate the number of all users + // これで、すべてのユーザー数を計算できます let totalUsers = 0 for (let i = 0; i < data.length; i++) { totalUsers += data[i].length } return
-

{totalUsers} users listed

+

{totalUsers} ユーザーがリストされています

{data.map((users, index) => { - // `data` is an array of each page's API response. + // `data` は、各ページの API レスポンスの配列です return users.map(user =>
{user.name}
) })} - +
} ``` -The `getKey` function is the major difference between `useSWRInfinite` and `useSWR`. -It accepts the index of the current page, as well as the data from the previous page. -So both index based and cursor based pagination API can be supported nicely. +`getKey` 関数は、`useSWRInfinite` と `useSWR` とで大きな違いがあります。 +現在のページのインデックスに加えて、前のページのデータも受け入れます。 +したがって、インデックスベースとカーソルベースの両方のページネーション API を適切にサポートできます。 -Also `data` is no longer just one API response. It's an array of multiple API responses: +また、`data` は一つの API レスポンスだけではありません。複数の API レスポンスの配列になります: ```js -// `data` will look like this +// `data` はこのようになります [ [ { name: 'Alice', ... }, @@ -298,9 +298,9 @@ Also `data` is no longer just one API response. It's an array of multiple API re ] ``` -### Example 2: Cursor or Offset Based Paginated API +### 例 2: カーソルまたはオフセットにもとづいたページネーション API -Let's say the API now requires a cursor and returns the next cursor alongside with the data: +API がカーソルを必要とし、データと一緒に次のカーソルを返すとしましょう: ``` GET /users?cursor=123&limit=10 @@ -315,27 +315,27 @@ GET /users?cursor=123&limit=10 } ``` -We can change our `getKey` function to: +`getKey` 関数を次のように変更できます: ```jsx const getKey = (pageIndex, previousPageData) => { - // reached the end + // 最後に到達した if (previousPageData && !previousPageData.data) return null - // first page, we don't have `previousPageData` + // 最初のページでは、`previousPageData` がありません if (pageIndex === 0) return `/users?limit=10` - // add the cursor to the API endpoint + // API のエンドポイントにカーソルを追加します return `/users?cursor=${previousPageData.nextCursor}&limit=10` } ``` -### Advanced Features +### 高度な機能 -[Here is an example](/examples/infinite-loading) showing how you can implement the following features with `useSWRInfinite`: +`useSWRInfinite` を使って次の機能を実装する方法は、[こちらに例があります](/examples/infinite-loading): -- loading states -- show a special UI if it's empty -- disable the "Load More" button if reached the end -- changeable data source -- refresh the entire list +- 状態の読み込み +- 空のときには特別な UI を表示する +- 最後に到達したときには「さらに読み込む」ボタンを無効化する +- 変更可能なデータソース +- リスト全体を更新する