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

Reference to JSX Component generates inline function, a lost state and performance problem #3678

Open
playfulThinking opened this issue Dec 20, 2023 · 0 comments

Comments

@playfulThinking
Copy link

playfulThinking commented Dec 20, 2023

Description

When I pass a JSX.Component to React Navigation (https://reactnavigation.org) it gets compiled into an inline function call, which is inefficient in React (and React Native, which I'm using).

Repro code

in "WinScreen.fs"

[<JSX.Component>]
let TestScreen () =
    JSX.jsx $"""
    <View>
        <Text> Hi There </Text> 
    </View>
    """

in "App.fs"

[<JSX.Component>]
let Render2 () =
    JSX.jsx $"""
    <NavigationContainer>
            <Stack.Screen name="win" component={WinScreen.WinScreen} />
            </Stack.Navigator>
    </NavigationContainer>
    """ |> toReact

Expected and actual results

I expected the {WinScreen.WinScreen} reference to generate this:

<Stack.Screen name="win" component={WinScreen}  />

But it generates this inline function:

<Stack.Screen name="test" component={() => <WinScreen></WinScreen>} />

and I get this warning in Chrome DevTools console:

Looks like you're passing an inline function for 'component' prop for the screen 'test' (e.g. component={() => <SomeComponent />}). Passing an inline function will cause the component state to be lost on re-render and cause perf issues since it's re-created every render. You can pass the function as children to 'Screen' instead to achieve the desired behaviour.

I can solve this problem by writing:

emitJsStatement () "import {WinScreen} from '../src/WinScreen.fs.js'"

...
<Stack.Screen name="win" component={{WinScreen}}  />

which generates what I hoped to get:

<Stack.Screen name="win" component={WinScreen} />

I'm fine with doing this, but it's hacky.

Am I doing something wrong or is this an inadvertent un-optimization?
Thanks much!

Related information

  • Fable version: 4.5.0
  • Operating system: Mac Ventura 13.6.2
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

1 participant