Install
$ agentstack add skill-foxhound87-skills-mobx-react-form-computed ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo 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.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
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 →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
- Computed Field Props: Declarative functions in field definitions — best for simple derived values.
strictSelect: false: Required when computed functions access fields before they exist.- autorun(): Imperative, powerful — ideal for complex multi-field calculations like cart totals.
- Nested arrays: Use the
computedpath for array items (e.g.,products[].total). - Fine-grained rendering: Each product row as a separate
observer()minimizes re-renders. - Cleanup:
autorun()returns a disposer — call it on unmount. - 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.
- Author: foxhound87
- Source: foxhound87/skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.