Nativebase: How to wrap <Footer> in custom component and keep it's styling.

Created on 16 Nov 2016  路  11Comments  路  Source: GeekyAnts/NativeBase

Hi, i have a component which has a lot of Content and i thought it will be better if I refactor

<Footer> component as it had lots of functions and buttons to navigate around and i need to reuse it.

So I wrappered it in another component (FooterWrapper) and imported it in the parent component (ParentComponent) it was first in.

In the FooterWrapper component i return <Footer> .... </Footer>; and in the parent component i call <FooterWrapper> inside it's <Content> block.

It mainly looks like this.

export class FooterWrapper extends Component {
      render() {
         return <Footer> 
                          // Some code
                </Footer>
       }
}

Then in the parent i have

export default class ParentComponent extends Component {
     render() {
           return (
                 <Container>
                        <Content>
                               // So much stuff
                               <FooterWrapper />
                         </Content>
                  </Container>
              );
         }
}

Problem is, Footer gets to be shown but without Footers behaviour, as in it's not on the bottom of the page but it's on the end of everyother component.

But i need to reuse the footer and still keep it in the bottom.. I don't understand flex very much too and react-native newbie.

Please help or give reference. :)

Thanks.

Most helpful comment

@maotora NativeBase as of now does not support custom components.

For now you can do something like below example:

<Container>
  <Content>
    // So much stuff
  </Content>
  <Footer>
    <FooterWrapper />
  </Footer>
</Container>

All 11 comments

@maotora Try wrapping FooterWrapper in View

Also looking into your code, put your FooterWrapper outside Content

@maotora NativeBase as of now does not support custom components.

For now you can do something like below example:

<Container>
  <Content>
    // So much stuff
  </Content>
  <Footer>
    <FooterWrapper />
  </Footer>
</Container>

@SupriyaKalghatgi Hey your solution worked perfectly!

I was about to get into <Footer>'s styling so i can copy it to my code.

But this is awesome!

Thank you very much! :)

Thanks, helpful. I would like to create a component for my header, but the above approach does not work since header needs an enclosing tag:

<Button transparent>
   <Icon name='ios-arrow-back' />
</Button>
<Title></Title>
<Button transparent>
   <Text>Send Inspection</Text>
</Button>

Wrapping the above in a View tag causes the Header not to render properly (styling messed up and right button not displayed). Any ideas on how I can fix this?

I'm also having this kind of problem. How to wrap a footer so I don't have to repeat on every screen?

Not working:

const TABS = [{
      name: 'Home',
      icon: 'ios-home',
      scene: 'home',
    }, {
      name: 'Maps',
      icon: 'ios-map',
      scene: 'events',
    }];

class TabBar extends Component {
  onPress = (tab) => {
    // ...
  }

  render() {
    return (
      <View>
        {TABS.map((tab, index) => (
          <FooterTab key={tab.name}>
            <Button transparent onPress={() => this.onPress(tab, index)}>
              {tab.name}
              <Icon name={tab.icon} />
            </Button>
          </FooterTab>
        ))}
      </View>
    );
  }
}
class Home extends Component {
  render() {
    return (
      <Container>
        <Header>
          <Title>Home</Title>
        </Header>

        <Content></Content>

        <Footer>
          <TabBar />
        </Footer>
      </Container>
    );
  }
}

captura de pantalla 2016-12-25 a las 13 20 54

This works, but is not very _reacty_:

const TabBar = () => {
  const onPress = (tab) => {
    // ...
  };

  const tabs = [{
    name: 'Home',
    icon: 'ios-home',
    scene: 'home',
  }, {
    name: 'Maps',
    icon: 'ios-map',
    scene: 'events',
  }];

  return tabs.map((tab, index) => (
    <FooterTab key={tab.name}>
      <Button transparent onPress={() => onPress(tab, index)}>
        {tab.name}
        <Icon name={tab.icon} />
      </Button>
    </FooterTab>
  ));
};
        <Footer>
          {TabBar()}
        </Footer>

I found my error, I was creating multiple FooterTab.

Final and working code:

class TabBar extends Component {
  onPress = (tab) => {
    // ...
  }

  render() {
    const { ...props } = this.props;
    const tabs = [{
      name: 'Home',
      icon: 'ios-home',
      scene: 'home',
    }, {
      name: 'Maps',
      icon: 'ios-map',
      scene: 'events',
    }];

    return (
      <FooterTab {...props}>
        {tabs.map((tab, index) => (
          <Button key={tab.name} transparent onPress={() => this.onPress(tab, index)}>
            {tab.name}
            <Icon name={tab.icon} />
          </Button>
        ))}
      </FooterTab>
    );
  }
}
       <Footer>
          <TabBar />
        </Footer>

@jesouhaite08 It is mentioned earlier that, NativeBase as of now does not support custom components. This has been on our list, to be fixed with the rewrite of NativeBase.

For now you can wrap the custom Header/Footer components in View and this requires some extra styles.

<Container>
  <Header>
    <MyComponent />
  </Header>
  <Content padder>
    <Text>Custom Header and Footer</Text>
  </Content>
  <Footer>
    <MyComponent />
  </Footer>
</Container>

MyComponent.js

<View style={styles.headerAndFooter}>
  <Button transparent>
    <Icon name="ios-arrow-back" />
   </Button>
   <Title>Title</Title>
   <Button transparent>
     <Icon name="ios-menu" />
   </Button>
 </View>

Hey guys - I am not able to get any more than 3 tabs for iOS - using this approach:

  <FooterTab>
    <Button active vertical onPress={() => handleTabClick(data.state)}>
        <Text>{data.text}</Text>
        <Icon name={data.icon} />
      </Button>
  </FooterTab>

Tried most every approach for flex box to make it behave, but nope.

Was this page helpful?
0 / 5 - 0 ratings