Morton
Morton

Reputation: 5760

How to controll some actions or state outside when using react-navigation?

If I navigate A screen to B screen by react-navigation.

It will generate a Header automatically.

So if I want to add some button deal with like control state or call api on the Header.

I have to add static navigationOptions like this

class B extends Component {
  static navigationOptions = ({ navigation }) => ({
    title: `${navigation.state.params.barTitle}`,
    headerBackTitle: null,
    headerTintColor: '#fff',
    headerRight:
    <TouchableOpacity 
      style={{ flexDirection: 'row', paddingRight: 20 }}
      onPress={() => {
        callApi();
      }} 
    >
      <Text>Call API</Text>
    </TouchableOpacity>
  });

  // other code...
}

But it declare static navigationOptions under class B.

If I set all of my react-navigation settings on another folder:

navigator/index.js

import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { createBottomTabNavigator } from 'react-navigation-tabs';

import RootScreen from '../screens/RootScreen';
import LoginStack from './LoginStack';
import MainStack from './MainStack';

const RootStack = createSwitchNavigator(
  {
    RootScreen: RootScreen,
    LoginStack: LoginStack,
    MainStack: MainStack
  },
  {
    initialRouteName: 'RootScreen',
  }
)


const AppContainer = createAppContainer(RootStack);

export default AppContainer;

navigator/LoginStack.js

import { createStackNavigator } from 'react-navigation-stack';

import LoginScreen from '../screens/LoginScreen';
import A from '../screens/A';
import B from '../screens/B';

const LoginStack = createStackNavigator(
  {
    LoginScreen: { screen: LoginScreen },
    A: { screen: A },
    B: { screen: B }
  },
  {
    initialRouteName: 'LoginScreen',
    headerMode: 'none'
  }
);

export default LoginStack;

I can't figure it out, how do I achieve that control the state or call api actions on LoginStack.js file ?

Do not consider customization my Header. If I want to use react-navigation Header. Is the only way I have to declare static navigationOptions under class B ?

Upvotes: 0

Views: 218

Answers (1)

Raj Rohit Yadav
Raj Rohit Yadav

Reputation: 688

Your question is not clear enough.

From which file you are trying to call API in LoginStack.js? By control state, you mean Navigation State or Component State?

What I have understood is you want to call API in each route Screen as API is in the parent file.

You can pass screenProps to call api as shown below.(You can edit the render method to add custom Header)

import React from 'react';
import {View, Text, Button} from 'react-native';
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';

// Login Stack
import ScreenA from './ScreenA';
import ScreenB from './ScreenB';

const LoginStackRoute = createStackNavigator(
  {
    ScreenA: ScreenA,
    ScreenB: ScreenB
  },
  {
    initialRouteName: 'ScreenA',
    headerMode: 'none'
  }
);

var LoginStackContainer = createAppContainer(LoginStackRoute);

export default class LoginStack extends React.Component{
  alertTest(){
    alert('hi')
  }
  render(){
    return(
      <>
        <View style={{height:50,width:'100%', backgroundColor:'red'}}>
          <Text>Custom Header</Text>
        </View>
        <LoginStackContainer screenProps={{alertTest: ()=>this.alertTest()}}/>
      </>
    )
  }
} 

ScreenA or ScreenB can access the API in route file as

import React from 'react';
import {View, Text, Button} from 'react-native';


export default class ScreenA extends React.Component{
  render(){
    return(
      <View>
        <Text>This is Screen A</Text>
        <Button 
          title='alert'
          onPress={()=>{this.props.screenProps.alertTest()}}
        ></Button>
      </View>
    )
  }
}

Upvotes: 1

Related Questions