How can I pass props in react-navigation 4.x to screens without children constantly unmounting?

Viewed 42

The premise for my question is not new; I just don't understand what others have so far already said.

I've got a react-native app under version 4.x of react-native-navigation with a Stack Navigator, and I'm trying to pass custom props to individual Screens without rewriting my Screens to use the whole params concept. I've simplified this down to just the gist of it:

import { createAppContainer } from "react-navigation";
import { createStackNavigator } from "react-navigation-stack";
import { MyScreen} from './screens/MyScreen';

const generateNav = ((toInject) => createAppContainer(
  createStackNavigator({
    "ScreenA": {screen: (props) => <MyScreen {...props} {...toInject}/>}
  }, {initialRouteName: "ScreenA"})
));

export default class App extends React.Component {

  // ...

  render() {
    const toInject = {someKey: this.state.someValue};
    const Nav = generateNav(toInject);
    return (
      <View style={{ width: "100%", height: "100%" }}>
        <Nav/>
      </View>
    );
  }
}

This all works great until this.state.someValue changes, at which point MyScreen completely unmounts and remounts, which is causing enormous optimization issues.

This is, in essence, the same trick as described by Sabbiu Shah in How to pass props to 'screens'/components in react-navigation.

I believe it suffers from the same issue as discussed by Max in Pass props nicely to screens in react navigation, namely "old ones will be unmounting and new ones mounting every time".

skyboyer007 also discusses it, at https://www.reddit.com/r/reactjs/comments/evenz8/preventing_unmounting_remounting/:

Last one needs us be more focussed. If for native component "different type" check is obvious(like "div" === "div", "a" !== "span") for custom component check is less straightforward. See, for custom component React checks referential equality of constructor. Not displayName or alike.

What I can't find is anything like an official doc, guide, or link to say the React source code itself exploring what's going on here, and if people are just repeating common wisdom that may nonetheless be wrong, or if they're right. For instance, I assumed if I went to the trouble of specifying a key, as we do for <ListItem>, that this should be enough to convince the VirtualDOM not to jettison the dynamically generated children.

Or, in other React Native code, I have seen something like

<View>
  {renderComponent()}
</View>

and it doesn't seem to cause any trouble.

what's different here, and is there really no workaround besides using react-navigation params or Context?

0 Answers
Related