0

I am trying to load settings with AsyncStorage and set some props to next screen. I use sortBy value to sort the Database results.

If I pass props with screenProps from App and it causes more renders because it takes time for sortBy value to load. Since AuthLoadingScreen decides what to render, I want to decrease the amount of renders by passing props directly to MainList

AuthLoadingScreen.js

export default class AuthLoadingScreen extends Component {
    constructor(props) {
      super(props);
      this._bootstrapAsync();
    }

    // Fetch the token from storage then navigate to our appropriate place
    _bootstrapAsync = async () => {
      const userToken = await AsyncStorage.getItem('token');
      const sortValue = await AsyncStorage.getItem('sortBy');
      if (userToken) {

        this.props.navigation.navigate('App',{"sortBy":sortValue}); // I can't send this back to  MainList of AppStack
      } else {
        this.props.navigation.navigate('Onboarding');
      }
    };

    render() {
      return (
        <View>
          <ActivityIndicator />
          <StatusBar barStyle="default" />
        </View>
      );
    }
  }

App.js

export default class App extends Component<Props> {

  render() {
    return (
      <Root>
      <AppContainer/>
      </Root>
    );
  }
}

const AppStack = createStackNavigator(
  {
   MainList: {
      screen: MainListScreen // how to pass props from AppStack to MainListScreen ?
    },
    Settings: {
      screen: Settings,
    }
  },
  {
    initialRouteName:"MainList",
    defaultNavigationOptions: () => ({
      headerStyle: {
        backgroundColor: '#2196f3'
      },
      headerTintColor: 'white'
    })
  }
);

const AppNavigator = createSwitchNavigator(
  {
    AuthLoading: AuthLoadingScreen,
    Onboarding:Onboarding,
    App: AppStack, //logged in users
  },
  {
    initialRouteName: 'AuthLoading',
  }
);



const AppContainer = createAppContainer(AppNavigator);
Meanteacher
  • 2,031
  • 3
  • 17
  • 48
  • **App** it's your StackNavigator, you should send that to the screen you'd like. In that case, since **AuthLoading** (AuthLoadingScreen) it's your initial route, you should receive the data there. On AuthLoading you can access it `this.props.navigation.state.params.sortBy `. Check this: https://stackoverflow.com/a/45390937/7602110 – Abraham Jul 16 '19 at 22:08
  • I want to receive the params that I send from `AuthLoading` at `MainListScreen`. Because MainListScreen has the database and it needs the `sortBy` value. If I send it from AppContainer with `screenProps` it causes multiple renders. – Meanteacher Jul 16 '19 at 22:16
  • 1
    You can do instead: this.props.navigation.navigate('MainList', { sortBy: sortValue}); and then access sortBy, but I rather consider using [Redux](https://redux.js.org/) to manage the state of the whole application – Abraham Jul 16 '19 at 22:40
  • Thank you @CarlosAbraham it worked! I really didn't know I could navigate like that. Is there a any disadvantage of doing that? It didn't cause any problem when I tried. – Meanteacher Jul 17 '19 at 09:33

1 Answers1

0

You can try something like this:

AuthLoadingScreen.js

_bootstrapAsync = async () => {
  const userToken = await AsyncStorage.getItem('token');
  const sortBy = await AsyncStorage.getItem('sortBy');

  if (userToken) {
    this.props.navigation.navigate('App', { sortBy })
  } else {
    this.props.navigation.navigate('Onboarding');
   }
};

then in the MainListScreen file access sortBy like this:

MainListScreen.js

this.props.navigation.state.params.sortBy
Abraham
  • 8,525
  • 5
  • 47
  • 53