In Livewire, what do the magic actions $refresh, $set, $toggle and $parent do when used in a wire:click directive?
answer
- no PHP method needed
- $refresh: round trip, no method
- $set('prop', value) writes a property
- $toggle('bool') flips a boolean
- $parent.method() calls the parent
basics
~20 sLivewire's magic actions run without a method of your own: $refresh re-renders the component, $set('prop', value) assigns a public property, $toggle('prop') flips a boolean, and $parent.remove(3) calls an action or reads a property on the parent component.
solid answer
~40 sMagic actions are built-in calls you can use wherever an action name is expected. `wire:click="$refresh"` makes a server round trip that applies any pending property updates and re-renders the component without calling a method. `wire:click="$set('qty', 1)"` assigns a public property on the server, running the same update path (and hooks) as a bound input. `wire:click="$toggle('open')"` flips a boolean property. `wire:click="$parent.removeItem({{ $id }})"` calls an action on the parent Livewire component directly from the child's template, avoiding an event. `$dispatch('name')` and `$event` are the other magic helpers. They save you trivial one-line methods, but `$set` still writes a public property from the browser, so it is only as safe as that property already was.
code
html · 10 lines<div>
<button wire:click="$toggle('showDetails')">Details</button>
<button wire:click="$set('qty', 1)">Reset quantity</button>
<button wire:click="$refresh">Reload</button>
<button wire:click="$parent.removeItem({{ $lineId }})">Remove</button>
@if ($showDetails)
<p>Qty: {{ $qty }}</p>
@endif
</div>go deeper
Recall what each of $refresh, $set, $toggle and $parent does and write them in wire:click without a PHP method.
Explain that $set and $toggle update public properties through the normal update path and that $refresh does not run mount().
Decide between $parent and events on coupling grounds and remember $set exposes the same attack surface as wire:model.
Set guidelines on when magic actions keep components lean and when explicit methods document intent better for a large team.
## What a magic action is In Livewire, anything you can put in `wire:click` (or `wire:submit`, `wire:keydown` and so on) is normally the name of a public method. **Magic actions** are names starting with `$` that Livewire understands without you writing a method. They exist to remove trivial methods like `public function close() { $this->open = false; }`. ## The four core magic actions | Magic action | Example | What happens on the server | |---|---|---| | `$refresh` | `wire:click="$refresh"` | Round trip, pending updates applied, component re-rendered; no method called | | `$set` | `wire:click="$set('qty', 1)"` | Public property `qty` set to `1`, then re-render | | `$toggle` | `wire:click="$toggle('showDetails')"` | Boolean property flipped, then re-render | | `$parent` | `wire:click="$parent.removeItem(7)"` | Action `removeItem(7)` called on the parent component | Two more helpers are available in the same place: - `$dispatch('cart-updated')` dispatches a Livewire event from the browser. - `$event` exposes the DOM event, as in `wire:keydown.enter="search($event.target.value)"`. ## $refresh in detail `$refresh` is the simplest way to show fresh data, for example a "reload" button on a cart summary that reads from the database. Any values changed by deferred `wire:model` bindings are sent with the request, so they are applied before the re-render. It is also a common **listener target**: `<livewire:cart-line @saved="$refresh" />` refreshes the parent whenever the child dispatches `saved`. ## $set and $toggle in detail `$set('prop', value)` behaves like a property update coming from a bound input: the property is assigned on the server, and the component's property update hooks run. Use it for small UI state such as resetting a search field or choosing a tab. `$toggle('prop')` is the boolean shortcut: it flips `true` to `false` and back. Both only work on **public** properties, and both show why public properties are user input: anyone could call `$set` with any value from devtools, so validation and locking rules apply exactly as they would for `wire:model`. ## $parent in detail `$parent` gives a child component's template direct access to its parent Livewire component: ```html <button wire:click="$parent.removeItem({{ $line->id }})">Remove</button> ``` Compared with an event, it is direct and explicit: there is no chance of a listener that is never triggered or an event nobody hears. The trade-off is **coupling**: the child now assumes its parent has a `removeItem()` action, so it only fits children that are always used inside that parent. Events or a callback-style design suit reusable children better. ## Magic action or real method? | Need | Magic action | Write a method when | |---|---|---| | Re-render with fresh data | `$refresh` | You must also reload something first | | Set one property to a literal | `$set('tab', 'history')` | The value needs checks or side effects | | Flip a flag | `$toggle('open')` | Opening must also load data | | Ask the parent to act | `$parent.save()` | The child is reused under other parents | A method is also easier to test by name and to protect with authorization, which matters once the operation is more than UI state. ## Calling them from Alpine Inside Alpine expressions the same helpers exist on `$wire`, for example `$wire.$refresh()` or `$wire.$set('qty', 1)`. Calling them from JavaScript is its own topic; in Blade directives, the forms above are what you use. ## Common mistakes 1. Writing a PHP method just to flip a boolean or clear a field. 2. Expecting `$refresh` to re-run `mount()`; it does not, `mount()` only runs when the component is created. 3. Using `$parent` in a component that is also rendered at the top level, where there is no parent to call. 4. Assuming `$set` bypasses validation or locking; it goes through the same property update path as any client-side change.
- Does Livewire's $refresh re-run mount()?No. `$refresh` makes a round trip that rebuilds the component from its snapshot, applies pending updates and re-renders. `mount()` runs only when the component is first created, so data loaded there is not reloaded; derive fresh data in computed properties or render() if `$refresh` should show it.
- When would you choose an event over $parent in a Livewire child component?When the child is reused under different parents or when several components should react. `$parent` hard-wires the child to one parent's action name, while an event lets any interested component listen, and the child need not know who handles it.
$parent is like an intercom button in a hotel room that rings reception directly: faster than leaving a note in the lobby (an event), but it only works in a room that is wired to that reception.
saying these in an interview costs you the question
- $refresh re-mounts the component and re-runs mount()
- $set can change protected properties
- $set skips the property update path, so validation and locks do not apply
- $parent works through a broadcast event to every component on the page
- You must write a PHP method for every wire:click