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

Nesting React.functionComponent leads to weirdness - what am I misunderstanding? #640

Open
njlr opened this issue Jan 8, 2025 · 2 comments

Comments

@njlr
Copy link

njlr commented Jan 8, 2025

This:

let f =
  React.functionComponent (fun () -> Html.text "abc")

let app =
  React.functionComponent
    (fun () ->
      Html.div
        [
          f ()
          Html.text "ijk"
        ]
      )

Looks like this:

Screenshot 2025-01-08 at 19-28-18 Elmish

However, this:

let app =
  React.functionComponent
    (fun () ->
      Html.div
        [
          React.functionComponent (fun () -> Html.text "abc") ()
          Html.text "ijk"
        ]
      )

Looks like this:

Screenshot 2025-01-08 at 19-27-33 Elmish

What are the rules around calling React.functionComponent inside of a component?

@MangelMaxime
Copy link
Contributor

It seems like you should not use React.functionComponent anymore:

Feliz/Feliz/Internal.fs

Lines 17 to 28 in 6841c9b

let functionComponent
(renderElement: 'props -> ReactElement)
(name: string option)
(withKey: ('props -> string) option)
: 'props -> Fable.React.ReactElement =
name |> Option.iter (fun name -> renderElement?displayName <- name)
#if FABLE_COMPILER_3
Browser.Dom.console.warn("Feliz: using React.functionComponent in Fable 3 is obsolete, please consider using the [<ReactComponent>] attribute instead which makes Feliz output better Javascript code that is compatible with react-refresh")
#endif
fun props ->
let props = props |> propsWithKey withKey
Interop.reactApi.createElement(renderElement, props)

The warning is wrongly configured, and should be updated to something like #if FABLE_COMPILER_3 || FABLE_COMPILER_4 || FABLE_COMPILER_5 or even better React.functionComponent should just be removed.

But in theory, when creating a function component in React you store it in a variable and then use it later as shown in your first example.

@Zaid-Ajaj
Copy link
Owner

As @MangelMaxime, React.functionComponent is shouldn't be used any more because we have the [<ReactComponent>] attribute to decorate functions with:

let f = React.functionComponent (fun () -> Html.text "abc")

becomes:

[<ReactComponent>]
let F() = Html.text "abc"
  • Use [<ReactComponent>] on functions that are written in PascalCase (React convention)
  • Define those function as module-level functions or as a static method in a static class
  • Use tupled-parameters for React components f(key:string, value: string) instead of f (key:string) (value: string)

What are the rules around calling React.functionComponent inside of a component?

Basically you should never call (or use React.functionComponent) inside another component.

if you call the React function declaration where it is being declared like React.functionComponent (fun () -> Html.text "abc") () then it will lose its local state and cause weird behaviour like you are seeing in the example above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants