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

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 :)

Related

Native-base doesn't show footer component in my view React-native

I'm triyng to use the Footer component from native-base in my view, but i can't see nothing when i implement the code from: Footer component native-base
I don't know if maybe is a bug or if i need implement an aditional option in my code.
My code:
(I dont show Login.tsx because only use footer in Home view)'.
App.tsx
import {createStore} from 'redux';
import rootReducer from './Store/Reducers/Reducers';
const store = createStore(rootReducer);
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { loading: true };
}
async componentDidMount() {
await Font.loadAsync({
Roboto: require('native-base/Fonts/Roboto.ttf'),
Roboto_medium: require('native-base/Fonts/Roboto_medium.ttf'),
});
this.setState({ loading: false });
}
render(){
if (this.state.loading) {
return (
<Root>
<AppLoading />
</Root>
);
}
else {
return (
<Provider store={store}>
<Root>
<NavigationContainer>
<Navigator/>
</NavigationContainer>
</Root>
</Provider>
);
}
}
}
Navigator.tsx
import React from 'react'
import { createStackNavigator } from '#react-navigation/stack'
import Login from '../Views/Login'
import Home from '../Views/Home'
import Register from '../Views/Register'
const Stack = createStackNavigator();
const Navigator= () =>{
return (
<Stack.Navigator>
<Stack.Screen name="Login" component={Login} options={{headerShown:false}}/>
<Stack.Screen name="Home" component={Home} options={{title:'Home.'}}/>
<Stack.Screen name="Register" component={Register} options={{title:'Register.'}}/>
</Stack.Navigator>
);
}
export default Navigator;
Home.tsx (Only the footer here)
import React from 'react'
import {Footer, Icon, Button, Text, FooterTab, Container} from 'native-base'
import Styles from './Styles/HomeStyles'
import {connect} from 'react-redux'
const Home =(props) => {
const {users} = props;
return(
<Container style={Styles.container}>
{users.list !== undefined && users.list.length>0 ?
users.list.map(user=> (
<Text>Hello {user.nick}</Text>
))
: null
}
<Footer>
<FooterTab>
<Button vertical>
<Icon name="apps" />
<Text>Apps</Text>
</Button>
<Button vertical>
<Icon name="camera" />
<Text>Camera</Text>
</Button>
<Button vertical active>
<Icon active name="navigate" />
<Text>Navigate</Text>
</Button>
<Button vertical>
<Icon name="person" />
<Text>Contact</Text>
</Button>
</FooterTab>
</Footer>
</Container>
);
}
const mapStateToProps=(state)=>{
const {users} = state;
return {users};
}
export default connect(mapStateToProps)(Home);
The result in Home:
Try add Content before Footer, like that, Content is also imported from native-base, if it's still not working, try removing the style of the container
<Container>
<Content><Text>dsdsds</Text></Content>
<Footer>
<Button vertical>
<Icon name="apps" />
<Text>Apps</Text>
</Button>
</Footer>
</Container>

How do you solve: undefined is not an object (evaluating 'this.panResponder.panHandlers')?

Hi my friend how to solve this problem,I have the following sourcode :
import React, { Component } from 'react';
import { Container, Header, Content, SwipeRow, View, Text, Icon, Button } from 'native-base';
class SwipeRowExample extends Component {
render() {
return (
<Container>
<Header />
<Content scrollEnabled={false}>
<SwipeRow
leftOpenValue={75}
rightOpenValue={-75}
left={
<Button success onPress={() => alert('Add')}>
<Icon active name="add" />
</Button>
}
body={
<View>
<Text>SwipeRow Body Text</Text>
</View>
}
right={
<Button danger onPress={() => alert('Trash')}>
<Icon active name="trash" />
</Button>
}
/>
</Content>
</Container>
);
}
}
export default SwipeRowExample;
Message obtained: undefined is not an object (evaluating 'this.panResponder.panHandlers')
But the results displayed :
SwipeRow was removed from the latest version and they recommend react-native-swipe-list-view
to use SwipeRow change native base version to 2.12.0
SwipeRow (removed)

native base not over riding theme style

I have a componet like:
import React, { Component } from 'react'
import { StyleSheet } from 'react-native'
import { StyleProvider, Container, Content, Footer, FooterTab, Button, Icon } from 'native-base'
export default class MainFooter extends Component {
render() {
return (
<StyleProvider style={footerTabTheme}>
<Footer>
<FooterTab>
<Button>
<Icon name="ios-home" />
</Button>
<Button active>
<Icon name="ios-people" />
</Button>
<Button>
<Icon style={{fontSize: 45}} name="ios-radio-button-on-outline" />
</Button>
<Button>
<Icon name="md-medkit" />
</Button>
<Button>
<Icon name="ios-people" />
</Button>
</FooterTab>
</Footer>
</StyleProvider>
)
}
}
const footerTabTheme = {
"NativeBase.Button": {
".active": {
backgroundColor: "#c71818",
}
}
}
According to documentation I should be able to customize the active button background color for footer now.
But I am getting error about can not read androidRipple or something.
What is wrong in here ?
According to the documentation, you need wrap all UI inside the 'Container' component:
<StyleProvider style={...}>
<Container> {*<--------------*}
...
<Container>
</StyleProvider>

_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

Native Base Footer Nav Tabs

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>
)
}
}