Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@react.componentWithProps no longer works with @directive("'use memo'") #7293

Closed
nojaf opened this issue Feb 14, 2025 · 4 comments · Fixed by #7300
Closed

@react.componentWithProps no longer works with @directive("'use memo'") #7293

nojaf opened this issue Feb 14, 2025 · 4 comments · Fixed by #7300
Labels

Comments

@nojaf
Copy link
Collaborator

nojaf commented Feb 14, 2025

Playground

type props = {count: int}

let someBoolean = v => Js.Math.random_int(1, v) % 2 == 0

@react.componentWithProps
let make =
  @directive("'use memo'")
  props => {
    if someBoolean(5) {
      React.useState(_ => 5)->ignore
    }
    Array.fromInitializer(~length=props.count, idx => idx)
    ->Array.map(_ =>
      <span className="text-2xl text-yellow-500 icon-[mdi-light--star]" />
    )
    ->React.array
  }

no longer transforms the function name of make.

@nojaf nojaf added the bug label Feb 14, 2025
@nojaf
Copy link
Collaborator Author

nojaf commented Feb 14, 2025

At first glance, the ppx is working as expected.

// A.res
  type props = {count: int}

  @react.componentWithProps
  let make = @directive("'use memo'")
      props => {
        Jsx.int(props.count)
      }

leads to

[
  structure_item 
    Pstr_type Nonrec
    [
      type_declaration "props"  
        ptype_params =
          []
        ptype_cstrs =
          []
        ptype_kind =
          Ptype_record
            [
              
                Immutable
                "count"                 core_type 
                  Ptyp_constr "int" 
                  []
            ]
        ptype_private = Public
        ptype_manifest =
          None
    ]
  structure_item 
    Pstr_value Nonrec
    [
      <def>
        pattern 
          Ppat_var "make" 
        expression 
          attribute  "directive"
            [
              structure_item 
                Pstr_eval
                expression 
                  Pexp_constant PConst_string ("'use memo'",Some "*j")
            ]
          Pexp_fun
          arity:1
          Nolabel
          None
          pattern 
            Ppat_var "props" 
          expression 
            attribute  "res.braces"
              []
            Pexp_apply
            expression 
              Pexp_ident "Jsx.int" 
            [
              <arg>
              Nolabel
                expression 
                  Pexp_field
                  expression 
                    Pexp_ident "props" 
                  "count" 
            ]
    ]
  structure_item 
    Pstr_value Nonrec
    [
      <def>
        pattern 
          Ppat_var "make" 
        expression 
          Pexp_let Nonrec
          [
            <def>
              pattern 
                Ppat_var "A" 
              expression 
                Pexp_fun
                arity:1
                Nolabel
                None
                pattern 
                  Ppat_var "props" 
                expression 
                  Pexp_apply
                  expression 
                    Pexp_ident "make" 
                  [
                    <arg>
                    Nolabel
                      expression 
                        Pexp_ident "props" 
                  ]
          ]
          expression 
            Pexp_ident "A" 
    ]
]

when running ./cli/bsc -dparsetree A.res -only-parse -bs-jsx 4.

The problem doesn't occur with other attributes than @directive.
@xyz for example will lead to function A as expected.

I would guess, it happens a bit later in the game.
@cristianoc any thoughts or pointers?

@cristianoc
Copy link
Collaborator

It does transform the name right?
In both cases it defines both make and Playground where they alias each other.

@cristianoc
Copy link
Collaborator

As to why make is emitted with the body, and not Playground, perhaps the jsx transform should add the attribute to Playground, not make.

@cristianoc
Copy link
Collaborator

The file js_pass_tailcall_inline.ml has checks directive = None; to disable inlining when a directive is present.
Removing those checks restores the correct naming of the function, though it removes the directive at the same time.

@nojaf nojaf linked a pull request Feb 21, 2025 that will close this issue
@nojaf nojaf closed this as completed Feb 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants