> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sublay.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Use comments

> Stateful, cursor-paginated comment thread list with sorting

## Overview

`useFetchManyCommentsWrapper` is a stateful wrapper around [`useFetchManyComments`](/v8/hooks/comments/use-fetch-many-comments) that manages the list, the cursor and the sort for you. It lists one level of a thread: an entity's top-level comments (`entityId`) or a comment's direct replies (`parentId`). Use it for a custom thread view outside `CommentSectionProvider`.

The hook doesn't fetch until `entityId` or `parentId` is set. Changing the sort, or any prop, resets the list and fetches from the start.

Nested replies (`replyDepth` above `0`) come back inside each comment's `replies` exactly as the server delivers them — the hook doesn't track them. For per-comment "load more replies", use `CommentSectionProvider` with [`useReplies`](/v8/hooks/comments/use-replies).

For a user's comments across entities, use [`useFetchCommentsByUserIdWrapper`](/v8/hooks/comments/use-fetch-comments-by-user-id-wrapper).

## Usage Example

```tsx theme={null}
import { useFetchManyCommentsWrapper } from "@sublay/react-js";

function ReplyList({ commentId }: { commentId: string }) {
  const { comments, loading, error, hasMore, sortBy, setSortBy, loadMore } =
    useFetchManyCommentsWrapper({
      parentId: commentId,
      limit: 10,
      defaultSortBy: "createdAt",
      defaultSortDir: "asc",
      include: "user",
    });

  return (
    <div>
      <select value={sortBy} onChange={(e) => setSortBy(e.target.value as any)}>
        <option value="createdAt">Oldest</option>
        <option value="top">Top</option>
      </select>
      <ul>
        {comments.map((comment) => (
          <li key={comment.id}>{comment.content}</li>
        ))}
      </ul>
      {error && <p>Couldn't load replies.</p>}
      {hasMore && (
        <button onClick={() => loadMore()} disabled={loading}>
          Load more
        </button>
      )}
    </div>
  );
}
```

## Parameters

<ParamField body="entityId" type="string | null" optional>
  List this entity's top-level comments.
</ParamField>

<ParamField body="parentId" type="string | null" optional>
  List this comment's direct replies. With both set, `parentId` decides the level and `entityId` must match the parent's entity — otherwise the list is empty.
</ParamField>

<ParamField body="limit" type="number" optional>
  Comments per page. Default: `10`.
</ParamField>

<ParamField body="defaultSortBy" type="CommentsSortByOptions" optional>
  Initial sort: `"createdAt"`, `"top"` or `"controversial"`. Default: `"createdAt"`. `"new"` / `"old"` are deprecated aliases for `"createdAt"`.
</ParamField>

<ParamField body="defaultSortDir" type="&#x22;asc&#x22; | &#x22;desc&#x22;" optional>
  Initial sort direction; applies to every sort. Default: `"desc"`.
</ParamField>

<ParamField body="defaultSortByReaction" type="ReactionType" optional>
  With `sortBy: "top"`: the reaction to rank by (raw count). Server default: `"upvote"`.
</ParamField>

<ParamField body="include" type="&#x22;user&#x22; | &#x22;grants&#x22; | (&#x22;user&#x22; | &#x22;grants&#x22;)[]" optional>
  Related data to populate, at every level.
</ParamField>

<ParamField body="replyDepth" type="number" optional>
  Levels of replies to nest under each comment (`0`–`5`). Server default: `0`.
</ParamField>

<ParamField body="replyLimit" type="number" optional>
  Replies per comment in the nested levels. Server default: `3`.
</ParamField>

<ParamField body="replySortBy" type="CommentReplySortByOptions" optional>
  Sort for the nested levels. Defaults to the current sort.
</ParamField>

<ParamField body="replySortDir" type="&#x22;asc&#x22; | &#x22;desc&#x22;" optional>
  Sort direction for the nested levels. Defaults to the current direction.
</ParamField>

<ParamField body="replySortByReaction" type="ReactionType" optional>
  The reaction the nested levels rank by, when their sort is `"top"`.
</ParamField>

## Returns

<ResponseField name="comments" type="Comment[]">
  The fetched comments. Each `loadMore` appends the next page; a comment already in the list isn't added twice.
</ResponseField>

<ResponseField name="loading" type="boolean">
  `true` while a page is loading, and before `entityId` or `parentId` is first set. When both are removed after one was set, the list is cleared and `loading` is `false`.
</ResponseField>

<ResponseField name="error" type="Error | null">
  The last failure loading the list. Cleared when the next load starts. Call `loadMore()` to retry — `hasMore` stays `true` after a failure, and the retry asks for the same page again, including a first page that failed.
</ResponseField>

<ResponseField name="hasMore" type="boolean">
  `true` when more comments are available.
</ResponseField>

<ResponseField name="loadMore" type="() => Promise<void>">
  Loads the next page, or retries the page that failed. Does nothing while a page is loading or when `hasMore` is `false`, and never throws — failures land in `error`.
</ResponseField>

<ResponseField name="sortBy" type="CommentsSortByOptions">
  Current sort.
</ResponseField>

<ResponseField name="setSortBy" type="(sortBy: CommentsSortByOptions) => void">
  Changes the sort and reloads from the start.
</ResponseField>

<ResponseField name="sortDir" type="&#x22;asc&#x22; | &#x22;desc&#x22;">
  Current sort direction.
</ResponseField>

<ResponseField name="setSortDir" type="(sortDir: &#x22;asc&#x22; | &#x22;desc&#x22;) => void">
  Changes the sort direction and reloads from the start.
</ResponseField>

<ResponseField name="sortByReaction" type="ReactionType | undefined">
  The reaction `"top"` ranks by. Only sent with `sortBy: "top"`.
</ResponseField>

<ResponseField name="setSortByReaction" type="(reaction: ReactionType | undefined) => void">
  Changes the ranking reaction. While `sortBy` is `"top"` this reloads from the start; under any other sort the value is kept for later and nothing reloads.
</ResponseField>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.