Skip to Content
DocsComputed Fields

Dynamic Computed Fields

Computed fields are form values derived reactively from other form fields or external React state variables. They stay in sync automatically and are treated as first-class members of your form values.


Defining Computed Fields

To define computed fields, pass a computed object config into useForm.

const form = useForm({ defaultValues: { quantity: 1, price: 10, }, computed: { // Defines 'total' as a derived value total: { deps: ["quantity", "price"], fn: (values) => values.quantity * values.price, }, }, });

Whenever the quantity or price inputs change, Formly recalculates the total field value in the background. You can access it directly via form.values.total.


Depending on External React State & Props

If a computed field depends on external variables (like component props, parent context, or React state outside of Formly’s form values), you can add them directly to the deps array.

Formly distinguishes between dependencies:

  • String values (e.g. "quantity") target form field paths.
  • Non-string values (e.g. state variables, props, objects) trigger reactive recalculations whenever they change.

Example: Product Invoice with External Tax Rate State

Here, changing either the form field subtotal or the React state taxRate will trigger a calculation of the computed field total:

import React, { useState } from "react"; import { Form, useForm } from "@explita/formly"; export default function ProductInvoice() { // External React state const [taxRate, setTaxRate] = useState(0.15); const form = useForm({ defaultValues: { subtotal: 100 }, computed: { total: { // Formly watches the 'subtotal' path and watches the external 'taxRate' state value! deps: ["subtotal", taxRate], fn: (values) => values.subtotal * (1 + taxRate), }, }, }); return ( <Form use={form}> {/* Subtotal Form Field */} <form.Field name="subtotal" label="Invoice Subtotal ($)" render={(props) => <input {...props} type="number" />} /> {/* External Tax Rate Input */} <div style={{ marginTop: "1rem" }}> <label>Tax Rate Selector: </label> <input type="number" step="0.01" value={taxRate} onChange={(e) => setTaxRate(Number(e.target.value))} /> </div> {/* Computed Value displays in real-time */} <div style={{ marginTop: "1.5rem", fontWeight: "bold" }}> Calculated Total: ${form.values.total.toFixed(2)} </div> </Form> ); }

Dynamic Registration (form.compute)

You can also register a computed field dynamically after form initialization using the form.compute() method:

useEffect(() => { form.compute("discountedTotal", ["total", discount], (values) => { return values.total - discount; }); }, [form, discount]);
Last updated on