Skip to content

JSX: plain and preserve mode evaluate children and props in different orders #9104

Closed

Description

@cristianoc

Found by a bug hunt over the 16 commits from eb087382 to cd641cbc.

let el = <div title={note("t")} key={note("k")}> {React.string(note("c"))} </div>
  • Plain mode emits jsx("div", {children: note("c"), title: note("t")}, note("k")), which evaluates c, t, k.
  • Preserve mode emits <div key={note("k")} title={note("t")}>{note("c")}</div>, which after the usual JSX transform (TypeScript react-jsx) evaluates t, c, k.

Plain mode builds the props record in the record type's declaration order (translcore.ml#L1692-L1694). JsxDOM.domProps declares children second (JsxDOM.res#L23), so in plain mode children are evaluated before almost every attribute. The same holds for a component whose props type declares children before other fields. tests/build_tests/jsx_preserve_semantics checks that the two modes agree, but never logs children against an attribute. The JS is the same at b123b7c3.

Related: #8757 (the dict-spread ordering case that suite covers).

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions