skip to content

In a Livewire component, how do you run code whenever a user changes one public property, such as recomputing an order total?

level: juniorimportance: must knowfreq 58%

answer

  1. method named after the property
  2. updating runs before, updated after
  3. updatedQuantity() sees the new value
  4. your own assignments do not fire it

basics

~20 s

Define an updatedQuantity() method on the component: Livewire calls it after it writes a new quantity sent from the browser, so it can recompute the total. updatingQuantity() runs before the write; generic updating() and updated() receive the property name.

solid answer

~40 s

Livewire gives every public property two update hooks named after it: `updatingQuantity($value)` runs **before** the new value is written and `updatedQuantity($value)` runs **after**, so inside `updatedQuantity()` `$this->quantity` already holds the new value and you can recompute `$this->total`. Generic `updating($property, $value)` and `updated($property, $value)` fire for any property and get its name. The hooks fire when Livewire itself writes the property from outside your code: a client update from `wire:model`, a reactive prop from the parent, a finished upload. Assigning `$this->quantity++` inside an action does **not** fire them, so an action that changes quantity must recompute the total itself, or the total should be derived rather than stored.

code

php · 21 lines
php
<?php

use Livewire\Component;

new class extends Component {
    public $quantity = 1;
    public int $unitPrice = 1250; // cents
    public int $total = 1250;

    public function updatedQuantity(): void
    {
        // runs after a client update to $quantity
        $this->total = max(0, (int) $this->quantity) * $this->unitPrice;
    }

    public function addOne(): void
    {
        $this->quantity = (int) $this->quantity + 1; // no updatedQuantity()
        $this->total = $this->quantity * $this->unitPrice;
    }
};

go deeper

for a junior

Recall the naming rule, updated plus the StudlyCase property, and that updating runs before the write while updated runs after it.

for a middle

Explain that the hooks fire only when Livewire applies an incoming update, so actions that assign the property must recompute themselves.

for a senior

Show when to stop storing derived values and compute them on read instead, so two write paths cannot drift apart.

for a principal

Weigh hook-driven derived state against computed values as a team convention for large forms with many interdependent fields.

## The problem the hook solves A **Livewire component** is a PHP class whose **public properties** are the state the browser can see and change. On an order form, a user edits a quantity field bound to `$quantity`; the browser sends the new value to the server in an update request, and Livewire writes it onto the component before running any action and before rendering. Very often something else has to follow that change: the line total, a discount tier, a shipping estimate. The **update hooks** are Livewire's place for that follow-up code. ## The four hook shapes | Hook | When | Arguments | |---|---|---| | `updating($property, $value)` | before any property is written | full property path, incoming value | | `updatingQuantity($value)` | before `$quantity` is written | incoming value | | `updated($property, $value)` | after the write | full property path, new value | | `updatedQuantity($value)` | after `$quantity` is written | new value | The property-specific forms are built by prefixing the **StudlyCase** property name, so `$unitPrice` gives `updatedUnitPrice()`. Inside an `updating*` hook the property still holds the **old** value, which is what makes it the place to reject input: throwing an exception there stops the write. Inside an `updated*` hook the new value is already on `$this`, which is what makes it the place to derive other state. ## Recomputing the order total ```php public function updatedQuantity(): void { $this->total = (int) $this->quantity * $this->unitPrice; } ``` The `(int)` cast matters because a value typed into an input arrives from the browser as a string. ## What does NOT fire the hook This is the trap interviewers probe. The hooks run when Livewire writes a property from outside the component's own code, for example: - a client-side update, typically from an input bound with `wire:model`; - a `#[Reactive]` prop that the parent changed; - a file upload that finished and was assigned to its property. They do **not** run when your own PHP assigns the property. An action such as `increment()` that does `$this->quantity++` changes the value without calling `updatedQuantity()`. Livewire is not observing the object; it calls the hook only at the moment it applies an incoming update. If an action and an input can both change the quantity, either call the recompute method from both places, or stop storing the total at all and derive it on read (a computed property, owned by the components topic). ## Where the hooks sit in a request Update hooks exist only on **subsequent** requests, because the first render has no incoming updates. On an update request Livewire restores the component from its snapshot, runs `boot()` and `hydrate()`, then applies each incoming update: `updating*` hooks fire as each value is written, and all the `updated*` hooks fire **after every update in the request has been written**. Then any called action runs, then the view renders. So an `updatedQuantity()` that also reads `$this->discountCode` sees the discount code sent in the same request, and the render that follows shows the recomputed total. ## Practical rules 1. Put derivations in `updated*`, and validation or rejection in `updating*`. 2. Keep hooks cheap: they run on every matching update, and with a `.live` input that means every keystroke that is sent. 3. Do not call hooks from the browser: Livewire refuses a client call to a lifecycle method such as `updatedQuantity` with `DirectlyCallingLifecycleHooksNotAllowedException`. 4. Remember that hook methods can type-hint services, which Livewire resolves from the container. ## Generic versus property-specific hooks The generic `updated($property, $value)` is useful when several properties share one reaction, for example re-pricing the order whenever `quantity`, `couponCode` or `shippingMethod` changes. It receives the **full property path**, so it must branch on the name: - a `match` or `in_array` check on `$property` keeps the reaction targeted; - without such a check, the code runs for every property on the component, including ones that have nothing to do with pricing. The property-specific form is easier to read and cannot fire for the wrong field, so most teams reach for `updatedQuantity()` first and use the generic hook only for genuinely shared reactions. Both forms can coexist: Livewire calls the generic hook first and then the specific one. ## What an interviewer listens for A junior answer names `updatedQuantity()` and says it runs after the change. A stronger answer adds the `updating` counterpart, says that `$this` already holds the new value in `updated*`, and, above all, knows that the hook is tied to Livewire's update step rather than to the property itself, so actions that write the property must keep derived values in sync by other means.

  • How would you stop a user from setting the quantity to a negative number before it is stored?
    Use `updatingQuantity($value)`: it runs before the write, while `$this->quantity` still holds the old value. Throwing there stops the update; the more common route is validating the property with Livewire's validation support. For a value the client must never change at all, lock it instead of guarding it in a hook.
  • If a component defines both updated() and updatedQuantity(), which runs first for a quantity change?
    The generic `updated($property, $value)` runs first (followed by any trait-suffixed `updated` hooks), then the property-specific `updatedQuantity($value)`. Both run after every incoming update of the request has been written, so either one sees the final values.

saying these in an interview costs you the question

  • Says updatedQuantity() also fires when an action assigns $this->quantity.
  • Believes updatedQuantity() must be registered in a listeners array first.
  • Thinks updating hooks run after the value is already written.
  • Names the hook updated_quantity() in snake case.
  • Expects the hook to fire on the first page render.