Home > database >  Why I can not use inline function in component prop? Can you explain in detail by giving an example?
Why I can not use inline function in component prop? Can you explain in detail by giving an example?

Time:10-13

Note: The component prop accepts component, not a render function. Don't pass an inline function (e.g. component={() => }), or your component will unmount and remount losing all state when the parent component re-renders. See Passing additional props for alternatives.

This warning from the simulator. enter image description here

function HomeScreen(props: Object) {
  return (
    <Navigator initialRouteName="Empty1">
      <Screen
        name="Empty1"
        component={() => {
          return (
            <View>
              <Text>Example Text</Text>
            </View>
          );
        }}
      />
      <Screen name="Home1" component={HomeScreen1} />
    </Navigator>
  );
}

CodePudding user response:

It's warning you that component is going to be re-rendered every time screen is re-rendered. This is because every time the component arg is evaluated it returns a fresh inline function. (the prop changes every time thus it must always re-render)

Evaluation of the same inline function twice yields different objects. Eg.

let funcs = []
for (let i =0 ; i<2; i  ) {
  funcs.push(() => 1)
}
funcs[0] == funcs[1]
>>> false

You can wrap this is useCallback to get a stable function that only updates when it needs to (never in your case since it captures no state). More on hooks here

function HomeScreen(props: Object) {
  let component = useCallback(() => {
    return (
      <View>
        <Text>Example Text</Text>
      </View>
    );
  }, [] // no dependencies. This lambda will only be evaluated once.
  );
  return (
    <Navigator initialRouteName="Empty1">
      <Screen
        name="Empty1"
        component={component}
      />
      <Screen name="Home1" component={HomeScreen1} />
    </Navigator>
  );
}

Or since this function doesn't depend on anything stateful you could also just declare it globally at the top of this file.

let component = () => {
    return (
      <View>
        <Text>Example Text</Text>
      </View>
    );
  };

function HomeScreen(props: Object) {
    return (
    <Navigator initialRouteName="Empty1">
      <Screen
        name="Empty1"
        component={component}
      />
      <Screen name="Home1" component={HomeScreen1} />
    </Navigator>
  );
}

CodePudding user response:

You need to understand what is hiding behind JSX syntax.

When you use <SomeComponent/> it is added to the React Virtual DOM and exists there until the tree is changing and component has to be unmounted. It survives rerenders, the DOM is updating, but component lives.

When you use () => <SomeComponent /> this component is a new object on every rerender of the parent. If it has state (via setState hook) it will be reinitialized. If it has some code in useEffect(() => {}, []) hook it will be called again.

  • Related