Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 57 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ Provides a `useSubscribe()` hook for React which wraps Replicache's `subscribe()

React hook that allows you monitor replicache changes

| Parameter | Type | Description |
| :--------------- | :------------------------------------------ | :------------------------------------------------------------------------------- |
| `rep` | `Replicache` | Replicache instance that is being monitored |
| `query` | `(tx: ReadTransaction) => Promise<R>` | Query that retrieves data to be watched |
| `options?` | `Object \| undefined` | Option bag containing the named arguments listed below ⬇️ |
| `.default?` | `R \| undefined = undefined` | Default value returned on first render _or_ whenever `query` returns `undefined` |
| `.dependencies?` | `Array<any> = []` | List of dependencies, query will be rerun when any of these change |
| `.isEqual?` | `((a: R, b: R) => boolean) = jsonDeepEqual` | Compare two returned values. Used to know whether to refire subscription. |
| Parameter | Type | Description |
| :------------------- | :------------------------------------------ | :---------------------------------------------------------------------------------------------------------------- |
| `rep` | `Replicache` | Replicache instance that is being monitored |
| `query` | `(tx: ReadTransaction) => Promise<R>` | Query that retrieves data to be watched |
| `options?` | `Object \| undefined` | Option bag containing the named arguments listed below ⬇️ |
| `.default?` | `R \| undefined = undefined` | Default value returned on first render _or_ whenever `query` returns `undefined` |
| `.dependencies?` | `Array<any> = []` | List of dependencies, query will be rerun when any of these change |
| `.isEqual?` | `((a: R, b: R) => boolean) = jsonDeepEqual` | Compare two returned values. Used to know whether to refire subscription. |
| `.keepPreviousData?` | `boolean = true` | Preserves previous data during dependency transitions to eliminate UI flash. Set to `false` to reset immediately. |

## Usage

Expand Down Expand Up @@ -52,16 +53,63 @@ return (
);
```

## `keepPreviousData` Option

The `keepPreviousData` option (default: `true`) eliminates UI flash when navigating between views with different subscription dependencies.

### The Problem

When switching between subscriptions (e.g., navigating between categories), the hook traditionally resets to `undefined` or the default value, causing a brief flash of empty content before new data loads:

```
User switches from category "work" to "personal":
1. Hook unsubscribes from "work" → returns default: []
2. UI renders empty list (FLASH!)
3. New subscription fires with "personal" data
4. UI renders "personal" todos
```

### The Solution

With `keepPreviousData: true` (default), the hook preserves the previous subscription's data while the new subscription initializes:

```
User switches from category "work" to "personal":
1. Hook unsubscribes from "work" → KEEPS "work" data displayed
2. New subscription fires with "personal" data
3. UI renders "personal" todos (seamless transition)
```

### Disabling

Set `keepPreviousData: false` if you want to show the default value during transitions:

```typescript
const todos = useSubscribe(rep, tx => getTodosByCategory(tx, category), {
default: [],
dependencies: [category],
keepPreviousData: false, // Show [] during category switch
});
```

## Changelog

### 6.1.0

- Add `keepPreviousData` option (default: `true`) to eliminate UI flash during subscription transitions
- Add generation counter to prevent stale subscription callbacks from updating state
- Add isMounted guard to prevent setState after component unmount
- Improve error isolation in batched callbacks
- Add comprehensive JSDoc documentation

### 6.0.0

Remove `unstable_batchedUpdates` - no longer needed with React 19's automatic batching.
Requires React 19+. See https://react.dev/blog/2024/12/05/react-19

### 5.0.1

Change package to pure ESM. See See https://github.com/rocicorp/replicache-react/pull/61 for more information.
Change package to pure ESM. See https://github.com/rocicorp/replicache-react/pull/61 for more information.

### 5.0.0

Expand Down
Loading
Loading