Reference

Conditional logic in React forms

Showing a field only when an earlier answer warrants it is the point where most React forms start to rot. Done as component state it spreads across the file; done as data it stays one property on the field it belongs to.

The problem with doing it in components

Four conditional fields in a form built the usual way. Nothing here is wrong, and it is already hard to read.

function ApplicationForm() {
  const [employment, setEmployment] = useState('')
  const [hasKids, setHasKids] = useState(false)
  const [income, setIncome] = useState(0)

  const showEmployer = employment === 'employed' || employment === 'part-time'
  const showBusiness = employment === 'self-employed'
  const showDependants = hasKids
  const showSupport = hasKids && income < 40000

  return (
    <form>
      {/* ...and every one of these has to stay in sync by hand */}
      {showEmployer && <EmployerFields />}
      {showBusiness && <BusinessFields />}
      {showDependants && <DependantFields />}
      {showSupport && <SupportFields />}
    </form>
  )
}

The rules live in one place, the fields in another, and the state in a third. Adding a fifth condition means touching all three. Nothing tells you that showSupport depends on two answers, and nothing stops the next person adding a rule that contradicts an existing one.

The same rule as data

The condition becomes a property of the field it governs. There is no state to keep in sync, because the rule is evaluated from the answers the engine already holds.

{
  "id": "employer",
  "type": "short_text",
  "label": "Employer name",
  "showIf": {
    "field": "employment",
    "operator": "in",
    "value": ["employed", "part-time"]
  }
}

That is the whole change. The field knows when it applies, so reading the field tells you the rule — and deleting the field deletes the rule with it.

Combining conditions

Conditions nest with AND and OR, to any depth. This is the showSupport rule from the first example, which took two pieces of derived state.

{
  "id": "support",
  "type": "single_select",
  "label": "Do you receive support payments?",
  "showIf": {
    "combine": "AND",
    "conditions": [
      { "field": "hasKids", "operator": "eq", "value": true },
      { "field": "income", "operator": "lt", "value": 40000 }
    ]
  }
}

Branching whole sections

Conditions are not only for fields. A section can decide where the form goes next, which is how a questionnaire skips a branch that does not apply rather than showing empty steps.

{
  "id": "plan",
  "title": "Choose a plan",
  "exitAction": {
    "rules": [
      {
        "condition": { "field": "type", "operator": "eq", "value": "enterprise" },
        "jumpTo": "enterprise-details"
      }
    ],
    "default": "payment"
  }
}

Because the engine owns navigation, progress and step counts follow the branch automatically — the thing that is most often wrong in hand-built multi-step forms.

What you can compare

25 operators, covering equality, ordering, set membership, presence, substring and pattern matching, dates, array contents and length.

Equality & order

eq neq gt gte lt lte between

Sets & presence

in notIn exists notExists isEmpty isNotEmpty

Text

contains notContains startsWith endsWith matches matchesRegex

Dates & arrays

dateAfter dateBefore arrayContains arrayNotContains lengthGreaterThan lengthLessThan

The same expression drives showIf, disabled, conditional requiredand section jump rules — one syntax to learn, not four.

Why the order matters

A field’s visibility can depend on an answer that is itself computed from other answers. That makes the rules a dependency graph, not a list, and evaluating them in the order they happen to be written gives stale results on the first pass.

An engine resolves the graph instead. It is the part that is tedious to get right by hand and invisible when it works — which is why hand-built conditional forms tend to be correct until the day someone adds a rule in the wrong place.

Try it

The conditional demo on the homepage runs the real renderer against a real schema — tick the box and watch the field appear.

Related