Native Base Footer Nav Tabs - react-native

I am new to React Native and have created a footer with three button tabs. I am now wondering how to render different screens by clicking the buttons. My code:
export default class Uptown extends Component {
render() {
return (
<Container>
<Header>
<Title>Uptown</Title>
</Header>
<Content>
<App />
</Content>
<Footer>
<FooterTab>
<Button>
Contact
</Button>
<Button>
Here
</Button>
<Button>
Me
</Button>
</FooterTab>
</Footer>
</Container>
);
}
}
How would I go about changing screens when the buttons are pressed?

You can add conditional rendering instead of static <App/> tag. You can use code as following to render conditionally based on selected footer. (I used state variable to store selected page index. When index changed, render function automatically called by engine)
import First from './Home' // your first screen
import Next from './Next' // your second screen
class Updown extends Component {
constructor(props) {
super(props)
this.state = {index: 0} // default screen index
}
switchScreen(index) {
this.setState({index: index})
}
render() {
let AppComponent = null;
if (this.state.index == 0) {
AppComponent = First
} else {
AppComponent = Second
}
return (
<Container>
<Header><Title> Header... </Title></Header>
<Content> <AppComponent/> </Content>
<Footer>
<Button onPress={() => this.switchScreen(0) }> First </Button>
<Button onPress={() => this.switchScreen(1) }> Second </Button>
</Footer>
</Container>
)
}
}

I think as of native-base v2.3.1 (August 2017) the recommended way is to follow documentation on React Navigation / TabNavigator. Of course this is only if you actually intend to use TabNavigator (which I do) with the benefits of React Navigation (I'm not knowledgeable enough to say what those are).
But if you want the footer tabs to be part of the main navigation structure of your app, instead of an ad-hoc mechanism for one page, this seems to be the way to go.
import React, { Component } from "react";
import LucyChat from "./LucyChat.js";
import JadeChat from "./JadeChat.js";
import NineChat from "./NineChat.js";
import { TabNavigator } from "react-navigation";
import { Button, Text, Icon, Footer, FooterTab } from "native-base";
export default (MainScreenNavigator = TabNavigator(
{
LucyChat: { screen: LucyChat },
JadeChat: { screen: JadeChat },
NineChat: { screen: NineChat }
},
{
tabBarPosition: "bottom",
tabBarComponent: props => {
return (
<Footer>
<FooterTab>
<Button
vertical
active={props.navigationState.index === 0}
onPress={() => props.navigation.navigate("LucyChat")}>
<Icon name="bowtie" />
<Text>Lucy</Text>
</Button>
<Button
vertical
active={props.navigationState.index === 1}
onPress={() => props.navigation.navigate("JadeChat")}>
<Icon name="briefcase" />
<Text>Nine</Text>
</Button>
<Button
vertical
active={props.navigationState.index === 2}
onPress={() => props.navigation.navigate("NineChat")}>
<Icon name="headset" />
<Text>Jade</Text>
</Button>
</FooterTab>
</Footer>
);
}
}
));

You need to create a current index and bind the function to switch from a tab to another.
To do it use this :
import First from './First'
import Second from './Second'
class Updown extends Component {
constructor(props) {
super(props)
this.setState({currentIndex: 0}) // default screen index
}
switchScreen(index) {
this.setState({currentIndex: index})
}
render() {
let AppComponent = null;
//Here you can add as many tabs you need
if (this.state.currentIndex == 0) {
AppComponent = First
} else {
AppComponent = Second
}
return (
<Container>
<Header><Title> Header... </Title></Header>
<Content>
{AppComponent} // Load the component like this
</Content>
<Footer>
//HERE don't forget the bind function and pass the appropriate number
<Button onPress={() => this.switchScreen.bind(this,0) }> First </Button>
<Button onPress={() => this.switchScreen.bind(this,1) }> Second </Button>
</Footer>
</Container>
)
}
}
Hope it helps :)

I think that we can check some part of the #Hossein Mobasher code
import First from './Home' // your first screen
import Next from './Next' // your second screen
class Updown extends Component {
constructor(props) {
super(props)
this.state = {index: 0} // default screen index
}
switchScreen(index) {
this.setState({index: index})
}
render() {
let AppComponent = null;
if (this.state.index == 0) {
AppComponent = First
} else {
AppComponent = Second
}
return (
<Container>
<Header><Title> Header... </Title></Header>
<Content>
<AppComponent/> // you can write like this
</Content>
<Footer>
<Button onPress={() => this.switchScreen(0) }> First </Button>
<Button onPress={() => this.switchScreen(1) }> Second </Button>
</Footer>
</Container>
)
}
}

Related

React native Base - Sidebar opens underneath the screen

I'm two days trying to make a sidebar work using react native base.
I'm using the example I saw on the react native base website (https://docs.nativebase.io/Components.html#Drawer)
The sidebar is running (it opens). But there's been a kind of modal over the sidebar. The sidebar does not turn white. It gets dark as if it's underneath where it should be.
Look at the two pictures
I do not know what to do. Does anyone have an idea how to make this sidebar menu work? Here's the code I'm using
App.js
import React, { Component } from 'react'
import { Text } from 'react-native'
import { Header, Left, Button, Icon, Right, Body, Title, Drawer } from 'native-base'
import SideBar from './src/components/SideBar'
export default class AppHeader extends Component {
closeDrawer() {
this.drawer._root.close()
}
openDrawer() {
this.drawer._root.open()
}
render() {
return (
<Drawer
ref={(ref) => { this.drawer = ref; }}
content={<SideBar />}
onClose={() => this.closeDrawer()}
>
<Header>
<Left>
<Button transparent onPress={() => this.openDrawer()}>
<Icon name="menu" />
</Button>
</Left>
<Body>
<Title>Title</Title>
</Body>
<Right>
<Button transparent>
<Icon name="bulb" />
</Button>
</Right>
</Header>
</Drawer>
)
}
}
module.exports = AppHeader
SideBar.js
import React, { Component } from 'react';
import { Text } from 'react-native';
import {Content} from 'native-base';
export default class SideBar extends Component {
render() {
return (
<Content style={{backgroundColor:'#FFFFFF'}}>
<Text>Side Bar</Text>
</Content>
);
}
}
module.exports = SideBar;
try to insert the Container Tag inside Sidebar.class:
export default class SideBar extends Component {
render() {
return (
<Container>
<Content style={{backgroundColor:'#FFFFFF'}}>
<Text>Side Bar</Text>
</Content>
</Container>
);
}
}
alternatively you can try to follow (as I did) the structure of NativeBaseKitchenSink: https://github.com/GeekyAnts/NativeBase-KitchenSink

wants to show selected image in other component in reactNative

i have a problem i select an image from my phone gallery but now i want to pass it into an other component how i can achieve this ?
i have a component named as gallery in this component i render images from my phone gallery .and i can select any one image from gallery after that when i select a image i want to send it into an other component named as APPLYFILTER
here is my code of Component named as gallery which i used too get image from gallery
import React, { Component } from "react";
import { TouchableOpacity,StatusBar,View,Modal,
TouchableHighlight,StyleSheet,Image } from "react-native";
import { connect } from "react-redux";
import { DrawerNavigator, NavigationActions } from "react-navigation";
import {Icon} from 'react-native-elements';
import {
Container,
Header,
Title,
Content,
Text,
Button,
Left,
Body,
Right,
List,ListItem,Thumbnail,Footer,FooterTab
} from "native-base";
import { Grid, Row } from "react-native-easy-grid";
import CameraRollPicker from 'react-native-camera-roll-multi-picker';
export default class Search extends Component {
static navigationOptions = {
header: null
}
constructor(props) {
super(props);
this.state = {
pickedImage:null,
num:0,
selectSingleItem:true,
images:[],
};
}
getSelectedImages(images){
let image = images.length > 0 ? images[images.length-1] : null;
this.setState({pickedImage:image, images:images,num:images.length});
}
addfilter()
{
if(this.state.num>0)
{
this.props.navigation.navigate('AddFilter');
}
else{
alert('Please select a image');
}
}
render() {
return (
<Container>
<Header>
<Left>
<Button transparent active onPress={()
=>this.props.navigation.navigate('Home') }>
<Text style={{color:'#000'}}>Cancel</Text>
</Button>
</Left>
<Right>
<Button transparent onPress={this.addfilter.bind(this) }>
<Text style={{color:'#000'}}>Next</Text>
</Button>
</Right>
</Header>
<Content >
<View style={{height:300,}}>
<Image source={this.state.pickedImage} resizeMode={'stretch'}style={{ width: '100%', height:300 }} />
{/* {this.state.image} */}
</View>
<CameraRollPicker selectSingleItem='true'
callback={this.getSelectedImages.bind(this)} />
</Content>
<Footer>
<FooterTab>
<Button >
<Text >Gallery</Text>
</Button>
<Button>
<Text>Photos</Text>
</Button>
<Button >
<Text>Videos</Text>
</Button>
</FooterTab>
</Footer>
</Container>
);
}
}
const styles = StyleSheet.create({
container:{
flex: 1,
}
})
You can pass Image as props value to AddFilter component.
this.props.navigation.navigate('AddFilter',<Image Value>).

Dismiss modal when navigating to another screen

I have an App with Home Screen, in this screen I'm rendering a Modal which opens on button press, inside the Modal I have a button that is supposed to navigate me to another screen, it's navigating correctly but when I navigate to another screen the modal doesn't disappear, how can i hide it?
Adding the code to demonstrate
Home:
import React, { Component } from 'react';
import Modal from './Modal';
class Home extends Component {
state = {
isModalVisible: false
};
toggleModal = () =>
this.setState({ isModalVisible: !this.state.isModalVisible });
render() {
const { navigate } = this.props.navigation;
<Modal
visible={this.state.isModalVisible}
navigation={this.props.navigation}
/>
);
}
}
export default Home;
Modal:
import React, { Component } from "react";
import Modal from "react-native-modal";
class Modal extends Component {
render() {
const { navigate } = this.props.navigation;
return (
<Modal
isVisible={this.props.visible}>
<Button onPress={() => {navigate('Main')}}>
>Button</Text>
</Button>
</Modal>
);
}
}
export default Modal;
Ideally you should wait for the setState to finish inside the callback and then navigate to the screen, since the methods are async and may disrupt the state if navigate is called before setState has finished completing.
Also parent should control the state of the child.
Home
onNavigate = () => {
this.setState({isModalVisible: false}, () => this.props.navigation.navigate('Main')
}
<Modal
visible={this.state.isModalVisible}
onNavigate={this.onNavigate}
/>
Modal
<Modal
isVisible={this.props.visible}>
<Button onPress={this.props.onNavigate}>
<Text>Button</Text>
</Button>
</Modal>
You should provide a reference to the variable that defines the visibility state of the modal component. You'll need to define a function hides the modal and pass the function reference to the modal component and execute it on press of the button along side with the navigation action.
Something on the lines of -
Your home screen should have a function like -
onModalClose = () => {this.setState({isModalVisible: false})}
then pass this as reference to the modal component like -
<Modal
visible={this.state.isModalVisible}
navigation={this.props.navigation}
onModalClose={this.onModalClose}
/>
and call it on the onPress() method of the <Button/> component like-
<Button onPress={() => {this.props.onModalClose(); navigate('Main')}}>
EDIT
Just noticed, since you already have a function that toggles the visibility of your modal, you need not define a new function. You can pass that function reference to the modal component itself.
<Modal
visible={this.state.isModalVisible}
navigation={this.props.navigation}
onModalClose={this.toggleModal}
/>
I took Pritish Vaidya answer and made it usable for any screen.
Home
import React, { Component } from 'react';
import Modal from './Modal';
class Home extends Component {
state = {
isModalVisible: false
};
toggleModal(screenName) {
this.setState({isModalVisible: !this.state.isModalVisible });
if (screenName && screenName != '') {
this.props.navigation.navigate(screenName);
}
}
render() {
<Modal
visible={this.state.isModalVisible}
onDismiss={(screenName) => { this.toggleModal(screenName); }}
/>
);
}
}
export default Home;
Modal:
class Modal extends Component {
dismissScreen(screenName) {
const dismissAction = this.props.onDismiss;
dismissAction(screenName);
}
render() {
return(
<View style={{ flex: 1, padding: 20 }}>
<Button
title="Dismiss Modal"
onPress={() => {this.dismissScreen();}}
/>
<Button
title="Navigate to Other Screen"
onPress={() => {this.dismissScreen('ScreenName');}}
/>
</View>
);
}
}

error using reactnavigation: undefined is not object (evaluating _this2.props.navigation.navigate)

I got this error after tapping Categories Tab(Button):
undefined is not object (evaluating _this2.props.navigation.navigate)
it seems that the navigation property is not defined in AppFooter
I use nativebase for themeing.
App.js
...
import { AppRegistry } from 'react-native';
import { StackNavigator } from 'react-navigation';
export default class Home extends Component {
static navigationOptions = {
header: null,
}
render() {
return (
<StyleProvider style={getTheme(platform)}>
<Container>
<Header style={{justifyContent:'flex-end'}}>
. . .
</Header>
<Content>
. . .
</Content>
<AppFooter/>
</Container>
</StyleProvider>
);
}
}
const Pardisiha = StackNavigator({
Home: { screen: Home },
Category: { screen: Category },
});
AppRegistry.registerComponent('Pardisiha', () => Pardisiha);
AppFooter.js
import React, { Component } from 'react';
import { Footer, Button, FooterTab, Text, Icon } from 'native-base';
export default class Index extends Component {
render() {
return (
<Footer>
<FooterTab>
<Button vertical style={{paddingLeft:0,paddingRight:0}}>
<Icon name="person" />
<Text>Profile</Text>
</Button>
<Button vertical style={{paddingLeft:0,paddingRight:0}}>
<Icon name="search" />
<Text>Search</Text>
</Button>
<Button vertical style={{paddingLeft:0,paddingRight:0}} onPress={() => this.props.navigation.navigate('Category')} >
<Icon active name="list" />
<Text>Categories</Text>
</Button>
<Button vertical active style={{paddingLeft:0,paddingRight:0}} onPress={() => this.props.navigation.navigate('Category')} >
<Icon name="home" />
<Text>Home</Text>
</Button>
</FooterTab>
</Footer>
);
}
}
i have a solution for you, i have tried your code, and work in me.
you can add function to navigate your navigation and passing it into AppFooter Component, this is the function :
App.js
onNavigate = (Screen) =>{
this.props.navigation.navigate(Screen)
}
and then passing into your AppFooter, modify your code to this one:
App.js
<AppFooter onNavigate={this.onNavigate} />
and then if you want to call this function, modify to this one too:
AppFooter.js
<Button vertical style={{paddingLeft:0,paddingRight:0}} onPress={() => this.props.onNavigate('Category')} >
<Icon active name="list" />
<Text>Categories</Text>
</Button>
<Button vertical active style={{paddingLeft:0,paddingRight:0}} onPress={() => this.props.onNavigate('Home')} >
<Icon name="home" />
<Text>Home</Text>
</Button>
Hope can solving your problem, please notice me if you have another error, thanks :)

_this._drawer.open is not a function react-native

i am using drawer from native base for my react native application. when u click the menu button the drawer not open up and i get this error ( _this._drawer.open ) is not a fucntion what is the isse here is my code
import React, { Component } from 'react';
import {
AppRegistry,View
} from 'react-native';
import {ScrollableTab,TabHeading, Drawer, Container,Content, Header,
Title, Button, Left, Right, Body, Icon ,Text,Tab, Tabs } from 'native-base';
import SecondStatus from './component/StatusComponent';
import HeaderComponent from './component/headerComponent';
import Sports from './component/Sports';
import MainPage from './component/MainPage';
import SideBar from './component/SideBar';
export default class Point extends Component {
closeDrawer = () => {
this.drawer.close()
};
openDrawer = () => {
alert('asasa click');
console.log('asad--');
this._drawer.open();
};
render() {
return (
<Container>
<Drawer
ref={(ref) => { this._drawer = ref; }}
content={<SideBar />}
onClose={() => this.closeDrawer()} >
<Header >
<Left>
<Button transparent onPress={this.openDrawer}>
<Icon name='arrow-back' />
</Button>
</Left>
<Body>
<Title>UrduPoint</Title>
</Body>
<Right>
<Button transparent onPress=
{this.openDrawer.bind(this)}>
<Icon name='menu' />
</Button>
</Right>
</Header>
</Drawer>
</Container>
);
}
}
AppRegistry.registerComponent('Point', () => Point);
here is my SideBar.js
import React, { Component } from 'react';
import {
Text,
View,
StyleSheet
} from 'react-native';
export default class SideBar extends Component{
render(){
return(
<View>
<Text>
asad
</Text>
</View>
)
};
}
ps. this drawer is same as in npm 'react-native-drawer'
According to the native base documentation, you should call:
this.drawer.root.open()
I have used react-native-drawer this npm thats work for me
Here is a very basic working example using native-base
import React, { Component } from 'react';
import {
Container,
Header,
Left,
Button,
Icon,
Body,
Title,
Right,
Content,
Drawer,
Text
} from 'native-base';
import {
StyleSheet,
View,
ScrollView
} from 'react-native';
class SideBar extends Component {
render() {
return (
<Container>
<Content
bounces={false}
style={{ flex: 1, backgroundColor: '#fff', top: -1 }}
>
<Button transparent>
<Text>Action</Text>
</Button>
</Content>
</Container>
);
}
}
export default class Core extends Component {
openDrawer() {
this._drawer._root.open();
}
closeDrawer() {
this._drawer._root.close();
}
render() {
return (
<Drawer
ref={(ref) => { this._drawer = ref; }}
content={<SideBar navigator={this._navigator} />}
onClose={() => this.closeDrawer()}
>
<Container>
<Header>
<Left>
<Button
transparent
onPress={() => this.openDrawer()}
>
<Icon name='menu' />
</Button>
</Left>
<Body>
<Title>TITLE</Title>
</Body>
<Right />
</Header>
<Content>
</Content>
</Container>
</Drawer>
);
}
}
Here is the sample example of NativeBase Drawer provided in its docs with a note saying You need to create your own SideBar component and import it.
Drawer Sample Code
import React, { Component } from 'react';
import { Drawer } from 'native-base';
import SideBar from './yourPathToSideBar';
export default class DrawerExample extends Component {
render() {
closeDrawer = () => {
this.drawer._root.close()
};
openDrawer = () => {
this.drawer._root.open()
};
return (
<Drawer
ref={(ref) => { this.drawer = ref; }}
content={<SideBar navigator={this.navigator} />}
onClose={() => this.closeDrawer()} >
// Main View
</Drawer>
);
}
}
Check for Sidebar Sample Code from NativeBase-KitchenSink
this._drawer._root.open()
is working for me