# Lwc Wire Refresh Patterns

> refreshApex, getRecordNotifyChange, and RefreshView API for LWC data refresh: when wired data is stale, forcing re-fetch after imperative DML, cross-component refresh, 2024 RefreshView replacement of getRecordNotifyChange. NOT for @wire basics and reactive params — use lwc/wire-service-patterns. NOT for LDS create/update/delete — use lwc/lwc-lds-writes.

- Skill: `pranavnagrecha/lwc-wire-refresh-patterns` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds add pranavnagrecha/lwc-wire-refresh-patterns`
- Raw SKILL.md: https://api.skillmd.com/api/skills/pranavnagrecha/lwc-wire-refresh-patterns/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: PranavNagrecha (https://skillmd.com/u/pranavnagrecha)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/pranavnagrecha/lwc-wire-refresh-patterns

---


# LWC Wire Refresh Patterns

Activate when an LWC's `@wire`-provisioned data becomes stale after an imperative DML, child record change, or cross-component event. Salesforce offers several refresh primitives — `refreshApex`, `getRecordNotifyChange` (deprecated), the newer `RefreshView` API, and wire re-provisioning via parameter change — each fits a specific scenario.

## Before Starting

- **Identify the wire adapter.** Custom Apex wire? Use `refreshApex`. Standard `getRecord`? Use `RefreshView` (or legacy `notifyRecordUpdateAvailable`).
- **Know about RefreshView.** The `lightning/refresh` module shipped in Spring '23 (beta at launch, GA thereafter). It replaces Aura's `force:refreshView` and is the view-scoped alternative to `getRecordNotifyChange` for standard UI API refreshes.
- **Avoid forced re-render hacks** like nulling params then restoring — tends to break and confuses framework caching.

## Core Concepts

### refreshApex(wiredValue)

For custom Apex wires. Hold onto the raw wired value (not the destructured data) and call `refreshApex(this._wiredAccounts)`:

```
@wire(getAccounts, { filter: '$filter' })
wiredAccounts;

handleRefresh() { return refreshApex(this.wiredAccounts); }
```

### RefreshView API

Refresh signal across the page/view. The *publisher* side is an event dispatch:

```javascript
import { RefreshEvent } from 'lightning/refresh';
this.dispatchEvent(new RefreshEvent());
```

The *subscriber* side is imperative registration, not a wire. `RefreshView` is not a wire adapter and cannot be used with `@wire`. The `lightning/refresh` module exports four functions plus the event: `registerRefreshContainer()`, `registerRefreshHandler()`, `unregisterRefreshContainer()`, `unregisterRefreshHandler()`, and `RefreshEvent` (plus the `REFRESH_COMPLETE`, `REFRESH_COMPLETE_WITH_ERRORS`, `REFRESH_ERROR` status constants).

A leaf component participates by registering a handler in `connectedCallback()` and tearing it down in `disconnectedCallback()`:

```javascript
import { LightningElement } from 'lwc';
import { registerRefreshHandler, unregisterRefreshHandler } from 'lightning/refresh';

export default class RefreshHandler extends LightningElement {
    refreshHandlerID;

    connectedCallback() {
        this.refreshHandlerID = registerRefreshHandler(this, this.refreshHandler);
    }

    disconnectedCallback() {
        unregisterRefreshHandler(this.refreshHandlerID);
    }

    refreshHandler() {
        // must return a Promise so the container can await completion
        return refreshApex(this.wiredResult);
    }
}
```

A container component uses `registerRefreshContainer(this, this.refreshContainer)` and receives a promise it can inspect against `REFRESH_COMPLETE` / `REFRESH_COMPLETE_WITH_ERRORS` / `REFRESH_ERROR`. Registered handlers are invoked from the container node outward. Note that `registerRefreshHandler` returns an **ID**, and it is that ID — not the component — that you pass to `unregisterRefreshHandler`.

### notifyRecordUpdateAvailable (legacy)

`import { notifyRecordUpdateAvailable } from 'lightning/uiRecordApi';` — still works; informs LDS that specific records changed.

### Wire re-provision by param change

Changing a reactive `@wire` parameter re-runs the wire automatically. Useful when refresh is triggered by user action that changes context.

## Common Patterns

### Pattern: refreshApex after imperative DML

```
async save() {
    await updateAccount({ acc: this.acc });
    await refreshApex(this.wiredAccounts);
}
```

### Pattern: Dispatch RefreshEvent from a child after save

Child modal saves a record → dispatches `new RefreshEvent()` → parent (or the view) refreshes its wires.

### Pattern: Cross-component refresh via Lightning Message Service

Sibling components can't share wired data. Use LMS to publish a "data changed" event; siblings subscribe and call their own refresh.

## Decision Guidance

| Scenario | Refresh mechanism |
|---|---|
| Custom Apex wire, same component | refreshApex(wiredValue) |
| Standard getRecord, after save | RefreshView (RefreshEvent) or notifyRecordUpdateAvailable |
| Cross-view, global refresh | RefreshEvent at the app-level listener |
| Sibling components needing refresh | Lightning Message Service + per-component refresh |
| Param-driven context change | Reassign reactive @wire param |

## Recommended Workflow

1. Identify the wire adapter — custom Apex vs UI API.
2. For custom Apex: store the raw wired value; call `refreshApex` on it.
3. For UI API: dispatch `RefreshEvent` or call `notifyRecordUpdateAvailable`.
4. For sibling coordination: wire LMS; subscribe and refresh per-component.
5. Avoid param-nulling hacks.
6. Test refresh flows with Jest (mock `refreshApex` + wire adapters).
7. Document refresh ownership — which component is responsible for triggering refresh.

## Review Checklist

- [ ] Custom Apex wires use `refreshApex(rawWiredValue)`
- [ ] Standard wires use `RefreshEvent` or `notifyRecordUpdateAvailable`
- [ ] No param-null-then-restore hacks
- [ ] Cross-component refresh coordinated via LMS or parent
- [ ] Refresh triggers after imperative DML, not before
- [ ] Jest tests cover refresh flow
- [ ] Migration plan from deprecated `getRecordNotifyChange` documented

## Salesforce-Specific Gotchas

1. **`refreshApex` requires the RAW wired value, not the destructured `data`.** Store `wiredFoo` (full object) not `wiredFoo.data`.
2. **`getRecordNotifyChange` is deprecated.** Migrate to `RefreshView` + `notifyRecordUpdateAvailable`.
3. **Reassigning `@track` data to itself does NOT refresh wires.** Wires re-run only when reactive params change or explicit refresh is invoked.

## Output Artifacts

| Artifact | Description |
|---|---|
| Refresh pattern selection | Per wire / per trigger mapping |
| LMS channel for refresh signals | Cross-component plumbing |
| Migration plan | Legacy getRecordNotifyChange → RefreshView |

## Related Skills

- `lwc/lwc-wire-service` — wire fundamentals
- `lwc/lwc-lightning-message-service` — cross-component events
- `lwc/lwc-lds-writes` — updateRecord/createRecord semantics

