React-native-router-flux: Dynamic control tabbar display and hide

Created on 8 Sep 2017  路  10Comments  路  Source: aksonov/react-native-router-flux

Version

  • react-native-router-flux v^4.0.0-beta.21
  • react-native v0.44.3

Expected behaviour

I expected that I can dynamic control tabbar display and hide.
For example , there are two roles for user in my system. Different roles have different permissions,one of them has four Scenes on tabbar,and the other has five.When I log in with different roles, display the corresponding Scenes on tabbar.
At first,I use State to control Scenes display and hide,like this:
`

          <Scene key="root" panHandlers={null}>
            <Scene key="Login" component={Login} title="login"  hideNavBar={true}  />
            <Scene key='upPortal' lazy={true} tabs={true} hideNavBar={true}  >
                   <Scene key='index' title='index' hideNavBar={true} >
                        //other scene
                   </Scene>
                   <Scene key='project'  title='project'  hideNavBar={true} >
                       //other scene
                   </Scene>
                   {
                     this.state.flag?
                     <Scene key='business'   title='business' hideNavBar={true} >
                            //other scene
                     </Scene>:null
                   }
                   <Scene key='custom' title='custom'  hideNavBar={true} >
                           //other scene
                   </Scene>
                   <Scene key="myhome" title="myhome" hideNavBar={true} >
                       //other scene
                    </Scene>
           </Scene>
       </Scene>`

but it is not work.
Then I think that I can render the whole Router again when the user log in with different role ,but it is still not work.

I need help ,Is there a good solution to dynamic control one of the tabbar display and hide?

Most helpful comment

you can duplicate and control tabbar when you click button loggin:

       <Scene key='upPortal' lazy={true} tabs={true} hideNavBar={true}  >
               <Scene key='index' title='index' hideNavBar={true} >
                    //other scene
               </Scene>
               <Scene key='project'  title='project'  hideNavBar={true} >
                   //other scene
               </Scene>
                 <Scene key='business'   title='business' hideNavBar={true} >
                        //other scene
                 </Scene>
               <Scene key='custom' title='custom'  hideNavBar={true} >
                       //other scene
               </Scene>
               <Scene key="myhome" title="myhome" hideNavBar={true} >
                   //other scene
                </Scene>
       </Scene>

        <Scene key='upPortal2' lazy={true} tabs={true} hideNavBar={true}  >
               <Scene key='index' title='index' hideNavBar={true} >
                    //other scene
               </Scene>
               <Scene key='project'  title='project'  hideNavBar={true} >
                   //other scene
               </Scene>
               <Scene key='custom' title='custom'  hideNavBar={true} >
                       //other scene
               </Scene>
               <Scene key="myhome" title="myhome" hideNavBar={true} >
                   //other scene
                </Scene>
       </Scene>

....
_checkTabbar() {
if (condition) {
Action.upPortal();
}
Action.upPortal2();
}

All 10 comments

Hi, in my APP I want to show or hide the tabbar depending if the user is logged or not. I have this information in the store so the only thing that I have to do is check if the token exists.

This is what I have,

               <Tabs  key="listTabs"
                      swipeEnabled={true}
                      showLabel={true}
                      lazy={true}
                      tabBarPosition="top"
                      hideTabBar={this.props.token === null}
                >
                .....
                </Tabs>

@pgonzalez-santiago
Hi,I want to show or hide one of tabbar's children.When hideTabBar is true ,there will hide all of them.

Can anyone help me ?

It is not supported, sorry.

@aksonov but it's supported by v4? Or will be? Can you share some information about how to implement this kind of thing in v4? Or directions to open a PR for it?

@aksonov is this feature still not supported? it would be a huge help if we can do a conditional scene rendering...

@tasharofi @thebergamo
there is one solution for me which can help you.
1銆丆reate a separate componet that contains your tabbars
2銆両n this componet,deal with your business
3銆両mport this componet in your business componet

this is my CustomTabBar

const defaultIcon = [require('../../images/Index.png'),
               require('../../images/Business.png'),
               require('../../images/Tourists.png'),
               require('../../images/My.png')];

 const activeInco = [require('../../images/ActiveIndex.png'),
                require('../../images/ActiveBusiness.png'),
                require('../../images/ActiveTourists.png'),
                require('../../images/ActiveMy.png')];
const titleInfo = ['棣栭〉','涓氬姟','瀹㈡簮','鎴戠殑'];

const styles = StyleSheet.create({

    tabView:{
      position:"absolute",
      backgroundColor:"#fff",
      bottom:0,
      left:0,
      width:Dimensions.get('window').width,
      flexDirection:"row",
      paddingTop:10,
      borderTopWidth:1,
      borderColor:"#ececec"
    },
    marginTop10:{
      marginTop:5,
      marginBottom:5,
    },
    redIcon:{
      width:10,
      height:10,
      backgroundColor:'red',
      position:'absolute',
      right:25,
      top:5,
      borderRadius:5,
    },
})

const sonViewStyle4 = StyleSheet.create({
    sonView:{
      alignItems:"center",
      justifyContent:"center",
      width:(Dimensions.get('window').width)/3
    }
})
const sonViewStyle5 = StyleSheet.create({
    sonView:{
      alignItems:"center",
      justifyContent:"center",
      width:(Dimensions.get('window').width)/4
    }
})

export default class CustomTabBar extends Component {
  constructor(props){
    super(props);
    this.state={
      active:this.props.focused,
      barIndex:this.props.barIndex,
      isProject:false,
      checkIndex:this.props.checkIndex,
      user:{},
      sonViewStyle:sonViewStyle4,
      redFlag:false,
    };
  }

  componentDidMount(){
    this.loadCurrentUser()
  }

  componentWillReceiveProps(nextprops){
    if(nextprops && nextprops.isNeedRefresh == 1){
      this.loadCurrentUser()
    }
  }



  loadCurrentUser(){
    storage.load({
      key:keys.currentUser
    }).then(user=>{
      if (user) {
        if (user.projectManager) { //Different roles have different permissions
          this.setState({user:user,isProject:true,sonViewStyle:sonViewStyle5});
        }else {
          this.setState({user:user,isProject:false,sonViewStyle:sonViewStyle4});
        }
      }else {
        this.setState({user:null,isProject:false,sonViewStyle:sonViewStyle4});
      }
    }).catch(error=>{
      this.setState({user:null,isProject:false,sonViewStyle:sonViewStyle4});
    })
  }

  renderTab(item,index){
    if (!this.state.sonViewStyle) {
      return null;
    }
    if (!this.state.isProject&&index===1) {
      return null;
    }
    if (this.state.checkIndex === index) {
      return <TouchableHighlight key={index} underlayColor="transparent">
            <View style={this.state.sonViewStyle.sonView}>
                  <Image  source={activeInco[index]}/>
                  <Text style={[fonts.tinyText_Blue,styles.marginTop10]}>{titleInfo[index]}</Text>
            </View>
      </TouchableHighlight>
    }else {
      return <TouchableHighlight key={index} underlayColor="transparent" onPress={()=>{this.checkPress(index)}}>
            <View style={this.state.sonViewStyle.sonView}>
                  <Image  source={defaultIcon[index]}/>
                  <Text style={[fonts.tinyText_Gray,styles.marginTop10]}>{titleInfo[index]}</Text>
            </View>
      </TouchableHighlight>
    }
  }
  checkPress(checkIndex){
    switch (checkIndex) {
      case 0:
        Actions.reset('Index',{});
        break;
      case 1:
        Actions.reset('MyProject',{});
        break;
      case 2:
        Actions.reset('TouristIndex',{});
        break;
      case 3:
        Actions.reset('PersonalIndex',{});
        break;
      default:
        Actions.reset('Index',{});
    }
  }
  render() {
    return (
      <View style={styles.tabView}>
            {
              activeInco.map((item,key)=>{
                return this.renderTab(item,key)
              })
            }
      </View>
    );
  }
}

and then import CustomTabBar in the business Componet

import CustomTabBar from '../../commonComponents/tabBar/CustomTabBar';

...


render() {
    return (
    <CustomTabBar checkIndex={0} />
 )
}


There is a problem that can't be solved.When press tab icon ,business component will refresh everytime.it can not cache data.

Hope to be useful to you

you can duplicate and control tabbar when you click button loggin:

       <Scene key='upPortal' lazy={true} tabs={true} hideNavBar={true}  >
               <Scene key='index' title='index' hideNavBar={true} >
                    //other scene
               </Scene>
               <Scene key='project'  title='project'  hideNavBar={true} >
                   //other scene
               </Scene>
                 <Scene key='business'   title='business' hideNavBar={true} >
                        //other scene
                 </Scene>
               <Scene key='custom' title='custom'  hideNavBar={true} >
                       //other scene
               </Scene>
               <Scene key="myhome" title="myhome" hideNavBar={true} >
                   //other scene
                </Scene>
       </Scene>

        <Scene key='upPortal2' lazy={true} tabs={true} hideNavBar={true}  >
               <Scene key='index' title='index' hideNavBar={true} >
                    //other scene
               </Scene>
               <Scene key='project'  title='project'  hideNavBar={true} >
                   //other scene
               </Scene>
               <Scene key='custom' title='custom'  hideNavBar={true} >
                       //other scene
               </Scene>
               <Scene key="myhome" title="myhome" hideNavBar={true} >
                   //other scene
                </Scene>
       </Scene>

....
_checkTabbar() {
if (condition) {
Action.upPortal();
}
Action.upPortal2();
}

Another variant is to use tabBarComponent prop, that will render links for needed scenes dynamically.

If anyone ends up here and still struggles with this, I've found a pretty good answer myself using tabBarComponent as explained in the next example:
https://stackoverflow.com/questions/54872145/programatically-hiding-and-showing-individual-tabs-in-react-native-router-flux-t.

Was this page helpful?
0 / 5 - 0 ratings