AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Mobx React Form Computed

skill-foxhound87-skills-mobx-react-form-computed · by foxhound87

Reactive computed props and autorun for mobx-react-form — computed field values, autorun-derived totals, reactive row calculations.

No reviews yet
0 installs
22 views
0.0% view→install

Install

$ agentstack add skill-foxhound87-skills-mobx-react-form-computed

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-foxhound87-skills-mobx-react-form-computed)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Mobx React Form Computed? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Skill: mobx-react-form-computed

Mission

Guide the user through implementing reactive computed values and autorun-derived state in mobx-react-form.

Use this skill when the user needs to:

  • Define computed field values (dynamic values from other fields)
  • Calculate row totals in array forms (e.g., cart qty × amount)
  • Derive grand totals from multiple fields
  • Reactively update fields based on other field changes
  • Use MobX autorun() for complex derived state

Two Approaches

| Approach | When to Use | |----------|-------------| | Computed Field Props | Simple derived values based on other fields | | MobX autorun() | Complex multi-field calculations, side effects |

Computed Field Props

Basic computed value

The computed prop is a function that returns a dynamic value. It receives { form, field }:

const fields = ['myComputedField', 'mySwitch'];

const values = {
  myComputedField: ({ form, field }) =>
    form.$('mySwitch')?.value ? 'a' : 'b',
  mySwitch: false,
};

const types = {
  mySwitch: 'checkbox',
};

const form = new Form({ fields, values, types }, {
  options: { strictSelect: false }, // required for computed props
});

> Important: Set strictSelect: false because the computed function may access fields before they exist.

Computed props on any field property

In addition to value, computed functions can be defined on: label, placeholder, disabled, rules, related, deleted, validatedWith, validators, bindings, extra, options, autoFocus, inputMode.

const fields = {
  email: {
    label: ({ form, field }) =>
      form.$('useWorkEmail')?.value ? 'Work Email' : 'Personal Email',
    placeholder: ({ form }) =>
      form.$('useWorkEmail')?.value ? 'Enter work email' : 'Enter personal email',
    rules: 'required|email',
  },
  useWorkEmail: {
    type: 'checkbox',
    value: false,
  },
};

new Form({ fields }, { options: { strictSelect: false } });

Computed in separated mode

const fields = ['myComputedField', 'mySwitch'];

const computed = {
  myComputedField: ({ form }) => form.$('mySwitch')?.value ? 'a' : 'b',
};

new Form({ fields, computed, values: { mySwitch: false } }, {
  options: { strictSelect: false },
});

Computed for nested array fields

Use the special computed field prop with a full field path — applied when add() creates new items:

const fields = [
  "products[].name",
  "products[].qty",
  "products[].amount",
  "products[].total",
  "total"
];

const computed = {
  "products[].total": ({ field }) => {
    const qty = field.container()?.$("qty")?.value;
    const amount = field.container()?.$("amount")?.value;
    return qty * amount;
  },
  total: ({ form }) =>
    form.$("products")?.reduce((acc, field) =>
      acc + (field.$("total")?.value || 0), 0
    ),
};

const form = new Form({ fields, computed }, {
  options: { strictSelect: false, autoParseNumbers: true },
});

> Note: autoParseNumbers: true ensures qty and amount are treated as numbers.

MobX autorun() for Reactive Calculations

For more complex derived state, use MobX autorun() directly. This is ideal for the "cart/order" pattern:

Form setup

const fields = [
  'products',
  'products[].name',
  'products[].qty',
  'products[].amount',
  'products[].total',
  'orderTotal',
];

const values = {
  products: [
    { name: 'MacBook Pro', qty: 1, amount: 2499, total: 0 },
    { name: 'AirPods Pro', qty: 2, amount: 249, total: 0 },
  ],
};

const types = {
  'products[].qty': 'number',
  'products[].amount': 'number',
  'products[].total': 'number',
  'orderTotal': 'number',
};

const hooks = {
  onInit(form) {
    if (form.$('products').fields.size === 0) {
      form.$('products').add();
    }
  },
};

The autorun engine

import { autorun } from 'mobx';

function CartComponent({ form }) {
  const products = form.$('products');

  useEffect(() => {
    const disposer = autorun(() => {
      const orderTotalField = form.$('orderTotal');
      let grandTotal = 0;

      products.map((item) => {
        const qty = Number(item.$('qty')?.value) || 0;
        const amount = Number(item.$('amount')?.value) || 0;
        const rowTotal = Number((qty * amount).toFixed(2));
        item.$('total')?.set(rowTotal);
        grandTotal += rowTotal;
      });

      orderTotalField.set(Number(grandTotal.toFixed(2)));
    });

    return () => disposer(); // cleanup on unmount
  }, [form, products]);

  // ...
}

Observer components for fine-grained rendering

const ProductRow = observer(({ field, onDelete }) => (
  
    
    
    
    € {field.$('total')?.value ?? 0}
    Remove
  
));

const FormComponent = observer(({ form }) => {
  const products = form.$('products');

  return (
    
      {products.map((field) => (
         products.del(field.key)}
        />
      ))}
      Total: € {form.$('orderTotal').value}
       products.add()}>Add Product
    
  );
});

Computed Props vs autorun() — When to Use

| Aspect | Computed Field Prop | autorun() | |--------|-------------------|-----------| | Definition | In field configuration | In component useEffect | | Best for | Simple derived values | Complex multi-field calculations | | Nested arrays | Supported via computed path | Full control | | Side effects | No (pure functions) | Yes (set values, call APIs) | | Cleanup | Automatic | Manual (call disposer) |

Using autorun() for Computed Display

const autorunDisposer = autorun(() => {
  const full = `${firstName.value} ${lastName.value}`.trim();
  form.$('fullDisplay').set(full || '(empty)');
  setComputed(full || '(empty)');
});

MobX tracks every observable access inside autorun() — it re-runs whenever any accessed observable changes.

Derived Field Props (label, placeholder, disabled)

const fields = {
  discountCode: {
    label: ({ form }) =>
      form.$('hasDiscount')?.value ? 'Discount Code' : 'No discount available',
    disabled: ({ form }) =>
      !form.$('hasDiscount')?.value,
    rules: ({ form }) =>
      form.$('hasDiscount')?.value ? 'required|min:3' : '',
  },
  hasDiscount: {
    type: 'checkbox',
    value: false,
  },
};

new Form({ fields }, { options: { strictSelect: false } });

Key Takeaways

  1. Computed Field Props: Declarative functions in field definitions — best for simple derived values.
  2. strictSelect: false: Required when computed functions access fields before they exist.
  3. autorun(): Imperative, powerful — ideal for complex multi-field calculations like cart totals.
  4. Nested arrays: Use the computed path for array items (e.g., products[].total).
  5. Fine-grained rendering: Each product row as a separate observer() minimizes re-renders.
  6. Cleanup: autorun() returns a disposer — call it on unmount.
  7. Derived props: label, placeholder, disabled, etc. can also be computed functions.

Related Skills

  • [mobx-react-form-api](../mobx-react-form-api/SKILL.md) — Core API prerequisite
  • [mobx-react-form-validation](../mobx-react-form-validation/SKILL.md) — Validation setup
  • [mobx-react-form-observers-interceptors](../mobx-react-form-observers-interceptors/SKILL.md) — observe/intercept
  • [mobx-react-form-events](../mobx-react-form-events/SKILL.md) — Event hooks

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.