# Reminder hooks

> **Info:** This is release candidate documentation for **Stream Chat React Native SDK v10**. For the latest stable version, see the [latest version (v9)](https://getstream.io/chat/docs/sdk/react-native/).

These hooks read the reminder of one message and the user's reminder list. They're exported from `stream-chat-react-native` and `stream-chat-expo`.

Reminders and save for later are explained on [Reminders and save for later](https://getstream.io/chat/docs/sdk/react-native/v10/features/messaging/reminders-and-save-for-later/), and the reminder manager, `client.reminders`, on [Reminder manager](https://getstream.io/chat/docs/sdk/react-native/v10/reference/state/reminder-manager/).

Each entry gives the signature, then:

- **Returns:** what the hook gives back.
- **Reads:** the store or the context it reads.
- **Re-renders:** what makes the component render again.
- **Needs:** where the component must sit, and what the hook does outside that place.

## useMessageReminder

Returns the reminder of a message.

```ts
useMessageReminder(messageId: string): Reminder | undefined
```

- **Returns:** the message's `Reminder` from `client.reminders`, or `undefined` when the message has none. A reminder without a time is a "save for later" bookmark.
- **Reads:** `client.reminders.state`, field `reminders`: the entry for `messageId`.
- **Re-renders:** when the message gets a reminder or loses it. Not when the reminder itself changes, such as its time or its countdown: those are in `reminder.state`, which you read with `useStateStore`.
- **Needs:** `Chat`. Throws outside it.

`MessageHeader` calls it to decide whether to render `MessageReminderHeader` or `MessageSavedForLaterHeader`. A badge of your own reads the reminder, then its state:

```tsx
import { Text } from "react-native";
import type { ReminderState } from "stream-chat";
import {
  useMessageContext,
  useMessageReminder,
  useStateStore,
} from "stream-chat-react-native";

const reminderSelector = ({ remind_at, timeLeftMs }: ReminderState) => ({
  remindAt: remind_at,
  timeLeftMs,
});

export const ReminderBadge = () => {
  const { message } = useMessageContext();
  const reminder = useMessageReminder(message.id);
  const { remindAt, timeLeftMs } =
    useStateStore(reminder?.state, reminderSelector) ?? {};

  if (!reminder) return null;
  if (remindAt == null) return <Text>Saved for later</Text>;
  if (timeLeftMs == null || timeLeftMs <= 0) return <Text>Reminder due</Text>;

  return <Text>Due in {Math.ceil(timeLeftMs / 60000)} min</Text>;
};
```

`timeLeftMs` is refreshed by the reminder's timer, more often as the time gets closer: [Reminder state and timers](https://getstream.io/chat/docs/sdk/react-native/v10/features/messaging/reminders-and-save-for-later/#reminder-state-and-timers) explains the schedule.

## useQueryReminders

Returns the reminder list, kept in step with reminder events.

```ts
useQueryReminders(): {
  data: ReminderResponseData[];
  isLoading: boolean;
  loadNext: () => Promise<void>;
  setData: Dispatch<SetStateAction<ReminderResponseData[]>>;
}
```

- **Returns:**
  - `data`: the reminders to show. It starts from the paginator's loaded items, and follows the reminder events:
    - `reminder.created` adds the reminder and sorts the list by `remind_at`. It adds it whatever the paginator's filters are.
    - `reminder.deleted` removes it.
    - `reminder.updated` removes it when the update moves it out of its kind: from saved for later to timed or back, from overdue to upcoming, or from upcoming to overdue. With the filters `{}`, updates change nothing.

    When the paginator publishes new items, `data` is built from them again, so a reminder added only by an event stays until the next page loads or the list reloads.

  - `isLoading`: whether a page is loading.
  - `loadNext()`: loads the next page with `client.reminders.queryNextReminders()`, or the first page when none is loaded.
  - `setData`: replaces `data`, for changes of your own.
- **Reads:** `client.reminders.paginator.state`, fields `items` and `isLoading`. It also listens for the three reminder events.
- **Re-renders:** when the paginator's items or loading state change, and when a reminder event arrives.
- **Needs:** `Chat`. Throws outside it.

It doesn't load a page by itself: call `loadNext()` or `client.reminders.queryNextReminders()` when the list mounts. Set `client.reminders.paginator.filters` before the first query, since setting the filters empties the list. [Your own reminder list](https://getstream.io/chat/docs/sdk/react-native/v10/features/messaging/reminders-and-save-for-later/#your-own-reminder-list) builds a "Saved for later" screen on it.

## Reminder stores without a hook

Read these stores with `useStateStore` and your own selector:

| To read                                     | Store and fields                                                                            |
| ------------------------------------------- | ------------------------------------------------------------------------------------------- |
| One reminder's time and countdown           | `reminder.state`, `remind_at` and `timeLeftMs`, with the reminder from `useMessageReminder` |
| The reminder list as the server returned it | `client.reminders.paginator.state`, `items`, `isLoading`, `hasMoreTail`, `lastQueryError`   |
| The offered times and the timer setting     | `client.reminders.configState`, `scheduledOffsetsMs` and `stopTimerRefreshBoundaryMs`       |

---

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react-native/v10/reference/hooks/reminder-hooks/](https://getstream.io/chat/docs/sdk/react-native/v10/reference/hooks/reminder-hooks/).