Explanation: I have working with react native in android.I started with the login screen and pass the parameter to another screen using API success call.i used a StackNavigation to navigate the screen. After successful login it will move to another screen with parameter.
Issue: API call is success but the navigation screen is not changed. fire an error like undefined is not a function (evaluating '_this.props.navigator('SecondScreen')')
I have post my all code over here.
index.android.js
// This is the entry point of an application. It will cal the first App.js.
/**
* Sample React Native App
* https://github.com/facebook/react-native
* #flow
*/
import React,{Component} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import App from './src/components/App';
import SecondScreen from './src/components/SecondScreen';
import {StackNavigator} from 'react-navigation';
export default class reactNavigationSample extends Component{
render(){
const {navigation} =this.props;
return(
<App navigation ={navigation}/>
);
}
}
const SampleApp = StackNavigator({
Home:{screen:App},
SecondScreen:{screen: SecondScreen}
});
AppRegistry.registerComponent('AwesomeProject', () => SampleApp);
App.js
// This file have a UI which is two TextInput and Button. When i click on button it will call the login method and the login method will call the API with the possible credentials of the login API. After successfull login it should move to another screen.
export default class App extends Component{
static navigationOptions ={
title : 'Home Screen',
}
constructor(props){
super(props);
navigate = props.navigation,
this.state={email:'',password:'',device_token:'',device_type:''};
}
login = () => {
fetch('http://span.mobiosolutions.com/api/v1/login',{
method:'POST',
headers:{
'Accept':'application/json',
'Content-Type':'application/json',
},
body:JSON.stringify({
email: this.state.username,
password: this.state.password,
device_token: 'aajdflkajdjfajdflkj',
device_type: '1'
})
})
.then((response) => response.json())
.then((res) => {
if(res.statusCode === 1){
console.log(res);
var username=res.message;
AsyncStorage.setItem('username',username);
this.props.navigator('SecondScreen')
}else{
alert(res.message);
}
})
.done();
}
render(){
const {navigate} = this.props.navigation;
return(
<View style={styles.container}>
<Image source={require('../img/background.jpg')} style={styles.backgroundImage}>
<View style={styles.content}>
<Text style={styles.logo}>- NATIVE -</Text>
<View style={styles.inputContainer}>
<TextInput underlineColorAndroid='transparent' style={styles.input}
onChangeText={(username) => this.setState({username})}
value={this.state.username}
placeholder='username' />
<TextInput secureTextEntry={true} underlineColorAndroid='transparent' style={styles.input}
onChangeText={(password) => this.setState({password})}
value={this.state.password} placeholder='password'/>
{/*<Button*/}
{/*onPress={() => navigate('SecondScreen')}*/}
{/*title="Login"/>*/}
<Button
onPress={this.login}
title="Login"/>
</View>
</View>
</Image>
</View>
)
}
}
const styles=StyleSheet.create({
container:{
flex:1,
justifyContent:'center',
alignItems:'center',
backgroundColor:'#F5FCFF',
},
backgroundImage:{
flex:1,
alignSelf:'stretch',
width:null,
justifyContent:'center',
},
welcome:{
fontSize:20,
textAlign:'center',
margin:10,
},
instructions:{
textAlign:'center',
color:'#333333',
marginBottom:5,
},
content:{
alignItems:'center',
},
logo:{
color:'white',
fontSize:40,
fontStyle:'italic',
fontWeight:'bold',
textShadowColor:'#252525',
textShadowOffset:{width:2,height:2},
textShadowRadius:15,
marginBottom:20,
},
inputContainer:{
margin:20,
marginBottom:0,
padding:20,
paddingBottom:10,
alignSelf:'stretch',
borderWidth:1,
borderColor:'#fff',
backgroundColor:'rgba(255,255,255,0.2)',
},
input:{
fontSize:16,
height:40,
padding:10,
marginBottom:10,
backgroundColor:'rgba(255,255,255,1)',
},
});
SecondScreen.js
const SecondScreen = () => {
return(
<View style={styles.container}>
<Text style={styles.welcome}>
THIS IS THE SECOND SCREEN.
</Text>
</View>
);
}
const styles=StyleSheet.create({
container:{
flex:1,
justifyContent:'center',
alignItems:'center',
backgroundColor:'#F5FCFF',
},
welcome:{
fontSize:20,
textAlign:'center',
margin:10,
},
instructions:{
textAlign:'center',
color:'#333333',
marginBottom:5,
},
});
SecondScreen.navigationOptions ={
title: 'Second Screen Title'
}
export default SecondScreen
Please help me solved out this issue in React Native. Thank you in advance.
There is a typo in the line in App.js
this.props.navigator('SecondScreen')
It should be
this.props.navigation.navigate('SecondScreen')
Related
I would like to display data on a Status header bar of Drawer Screen.
My code:
import React, {useEffect, useRef, useState} from 'react';
import {Dimensions, FlatList, Text} from 'react-native';
import {useDispatch, useSelector} from 'react-redux';
import AsyncStorage from '#react-native-async-storage/async-storage';
import {get_agency_direction} from '../store/Log/Dir/DirActions';
import Direction from '../screens/Direction/Direction';
import {createDrawerNavigator} from '#react-navigation/drawer';
const Drawer = createDrawerNavigator();
const RDirection = () => {`enter code here`
const info_agency = useSelector(state => state.DirReducers.info_agency);
const dispatch = useDispatch();
useEffect(() => {
try {
AsyncStorage.getItem('token').then(async value => {
dispatch(get_agency_direction(value));
});
} catch (e) {
console.log(e);
}
});
console.log(info_agency);
return (
<Drawer.Navigator
initialRouteName="Direction"
screenOptions={{
drawerStyle: {
width: Dimensions.get('window').width - 40,
},
}}
drawerType="permanent"
drawerContent={props => <DrawerDirection {...props} />}
backBehavior="history">
<Drawer.Screen
name="Direction"
component={Direction}
options={({navigation}) => ({
header: () => (
<HeaderUser
Gtitle='Noblesse voyages'
Depart="Douala"
Arrive="Yaoundé"
onPress={() => {
navigation.toggleDrawer();
}}
/>
),
headerStyle: {
height: 70,
},
})}
/>
</Drawer.Navigator>
);
};
export default RDirection;
The return code by console.log(info_agency) :
[{
"id":46,
"NomCh":"Bricks",
"PrenomCh":"Wandem foué",
"MotdepasseCh":"$2b$10$/4ugSQMptSp6VqScLcHl4.V9oyrgnAk7NNmtZIeRZ7usT1hcMsbB2",
"NumeroCh":673845359,
"NomAgence":"Talla voyages",
"NomOrganisation":"Talla",
"idch":49,
"CodesecureAgence":"$2b$10$lJ0oBoWr7vnI0Ix.YpWDo.tsiYJ8bSm/yLhVSDf8kgT4CfYFZm7Bm",
"NumeroSerieAg":"",
}]
I would have a truck like that
header: () => (
<HeaderUser
Gtitle={info_agency.NomAgence}
Depart={/* Not important*/}
Arrive={/* Not important*/}
onPress={() => {
navigation.toggleDrawer();
}}
/>
I tried with a Flatlist, but without success.
Your console.log shows that you're response returns an array. You're trying to call info_agency.NomAgence which won't work since it's not an object.
If you want to pass the title into Gtitle you would need to get the object form the array:
info_agency[0].NomAgence
I have a problem. When I display a map with #rnmapbox/maps and that I want to navigate in my screens, the app freeze then crashes. I'm pretty sure that this is a rnmapbox problem because when I remove the code between <MapboxGL.MapView> and <MapboxGL.MapView/>, navigation works fine.
I use #react-navigation/native and #react-navigation/native-stack
Note that this issus don't append on iOS, only on Android.
Record of the issue : https://vimeo.com/723749736
Here is my code :
App.js
import React from 'react';
import MapScreen from './src/screens/MapScreen';
import PlaceDetailsScreen from './src/screens/PlaceDetailsScreen';
import VideoPlayerScreen from './src/screens/VideoPlayerScreen';
import {createNativeStackNavigator} from '#react-navigation/native-stack';
import {NavigationContainer} from '#react-navigation/native';
import {SafeAreaProvider} from 'react-native-safe-area-context';
import {GestureHandlerRootView} from 'react-native-gesture-handler';
function App() {
const Stack = createNativeStackNavigator();
return (
<SafeAreaProvider>
<GestureHandlerRootView style={{flex: 1}}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Map"
component={MapScreen}
options={{headerShown: false}}
/>
<Stack.Group>
<Stack.Screen name="Details" component={PlaceDetailsScreen} />
<Stack.Screen
name="VideoPlayer"
component={VideoPlayerScreen}
options={{headerShown: false}}
/>
</Stack.Group>
</Stack.Navigator>
</NavigationContainer>
</GestureHandlerRootView>
</SafeAreaProvider>
);
}
export default App;
MapScreen.js
import React, {useState, useRef, useMemo, useCallback, useEffect} from 'react';
import {View, Text, PermissionsAndroid, Platform} from 'react-native';
import MapboxGL from '#rnmapbox/maps';
import BottomSheet, {BottomSheetScrollView} from '#gorhom/bottom-sheet';
import Styles from '../../Styles';
import PlaceBtn from '../components/PlaceBtn/PlaceBtn';
import IconPin from './../assets/icons/icon-locationPin.svg';
MapboxGL.setAccessToken(
'XXXXXXXXXXXXXXXXXXXXXXXXXXX',
);
function MapScreen({navigation}) {
const [hasGeolocPermission, setHasGeolocPermission] = useState(false);
const [currentRegion, setCurrentRegion] = useState([4.824, 45.76]); //longitude, latitude
const [userLocation, setUserLocation] = useState();
const [nearestPoints, setNearestPoints] = useState([]);
const markers = require('../data/markers.json');
const route = require('../data/route.json');
const routeLine = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: route.points,
},
},
],
};
const bottomSheetRef = useRef(null);
const snapPoints = useMemo(() => ['13%', '75%', '100%'], []);
const handleSheetChanges = useCallback(index => {
console.log('handleSheetChanges', index);
}, []);
const requestLocationPermission = async () => {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('location uses is granted');
setHasGeolocPermission(true);
} else {
console.log(granted);
console.log('location access denied');
}
} catch (error) {
console.warn('error while request location : ', error);
}
}
};
useEffect(() => {
requestLocationPermission();
}, []);
return (
<View style={Styles.container}>
<MapboxGL.MapView style={Styles.map} scaleBarEnabled={false}>
<MapboxGL.UserLocation
animated
showsUserHeadingIndicator
minDisplacement={1}
onUpdate={position => {
console.log('position : ', position);
}}
/>
<MapboxGL.Camera centerCoordinate={currentRegion} zoomLevel={14} />
{markers.map((marker, index) => {
if (marker.category === 'introduction') {
console.log('intro');
} else {
return (
<MapboxGL.PointAnnotation
key={index}
id={marker.id + ''}
coordinate={[marker.longitude, marker.latitude]}>
<IconPin width={35} height={35} fill={'#00c0aa'} />
</MapboxGL.PointAnnotation>
);
}
})}
<MapboxGL.ShapeSource id="line1" shape={routeLine}>
<MapboxGL.LineLayer
id="linelayer1"
style={{lineColor: 'red', lineWidth: 5}}
/>
</MapboxGL.ShapeSource>
</MapboxGL.MapView>
<BottomSheet
ref={bottomSheetRef}
handleIndicatorStyle={Styles.handleIndicator}
index={0}
snapPoints={snapPoints}
onChange={handleSheetChanges}>
<View style={Styles.bottomSheetContent}>
<Text style={Styles.bottomSheetTitle}>{route.name}</Text>
<BottomSheetScrollView>
{markers.map((place, index) => {
return (
<PlaceBtn
place={place}
navigation={navigation}
//isNear={nearestPoints.includes(place.id)}
/>
);
})}
</BottomSheetScrollView>
</View>
</BottomSheet>
</View>
);
}
export default MapScreen;
PlaceDetailsScreen.js
import React from 'react';
import {View, Text, TouchableOpacity} from 'react-native';
function PlaceDetailsScreen({navigation}) {
return (
<>
<TouchableOpacity
style={{backgroundColor: '#00FF00'}}
onPress={() => navigation.navigate('Map')}>
<Text>Go to MAP</Text>
</TouchableOpacity>
<TouchableOpacity
style={{backgroundColor: '#00FF00'}}
onPress={() => navigation.navigate('VideoPlayer')}>
<Text>Go to Video Player</Text>
</TouchableOpacity>
</>
);
}
```
I had the same problem. In my case I have a modal that is persistent through all screens and that modal shrinks when user swipes down like in youtube. After I initialized map inside modal, whenever I try to change screen my app were first freezing then crashing.
My solution was to render map only when modal is expanded. So I made a conditional rendering. Checked whether modal is shrinked or not. If shrinked, then render the map, else don't render. Thus my navigation worked without any problem.
This was my case and that's how I solved it:
// I use reduxjs toolkit.
// Since this modal is gonna be persistent through all screens
// It's best to store translateY value in redux.
const Modal = useAppSelector((state) => state.Modal);
const translateY = useSharedValue(Modal.translateY);
// I watch this variable with an useEffect hook to dynamically update redux value
const [translateYState, setTranslateYState] = useState(translateY.value);
useEffect(() => {
dispatch(setTranslateY(translateYState));
}, [translateYState]);
// translateYState's value is dynamically updating by a pan gesture detector
// translateYState value to be 0 means modal is expanded and user is using the modal
return (
<>
{translateYState==0 && (
<MapboxGL.MapView style={styles.map}></MapboxGL.MapView>
)}
</>
)
You can un-render the map when the modal which has title "Les Sens de Lyon" expands. If you are worried about your map data, you can store the map data for example all locations of markers in redux to be persistent but if your app is a single page app it should not be a problem else you can use redux.
I'm using react native expo for the following project basically i want to retrive the selected item form an flat list and display it in a modal
import React,{ Component}from 'react';
import {View,Text,Image,StyleSheet,Modal,Button} from 'react-native';
import { FlatList, TouchableOpacity, ScrollView } from 'react-native-gesture-handler';
import Card from '../shared/card';
import { AppLoading } from 'expo';
import * as Font from 'expo-font';
export default class MealSearch extends Component{
constructor(props){
super(props)
this.state = {
loaded:false,
show:false,
key:''
}}
render(){
const meal= [ {title:'My hero Academia',img:{uri:'https://i.cdn.turner.com/adultswim/big/img/2018/05/10/MHA_Header.png'}, body:'Rating : 4.5/5' , id :'1'},
{title:'Naruto',img:{uri:'https://store-images.s-microsoft.com/image/apps.15041.71343510227343465.377174a9-abc8-4da3-aaa6-8874fdb9e2f5.00fc0a9e-295e-40ca-a391-58ed9f83e9a0?mode=scale&q=90&h=1080&w=1920&background=%23FFFFFF'}, body:'Rating : 5/5' , id :'2'},
{title:'Attack On Titan',img:{uri:'https://www.denofgeek.com/wp-content/uploads/2013/12/attack-on-titan-main.jpg?fit=640%2C380'}, body:'Rating : 4.5/5' , id :'3'},
{title:'Fate: Unlimited Blade Works',img:{uri:'https://derf9v1xhwwx1.cloudfront.net/image/upload/c_fill,q_60,h_750,w_1920/oth/FunimationStoreFront/2066564/Japanese/2066564_Japanese_ShowDetailHeaderDesktop_496a6d81-27db-e911-82a8-dd291e252010.jpg'}, body:'Rating : 4.5/5' , id :'4'}
]
const handlePress = (meal_data) =>{
this.setState({show: true});
this.setState({selectedMeal:meal_data});
console.log(meal_data)
}
return(
<View style={styles.view} >
<FlatList
keyExtractor={item => item.id}
data={meal}
renderItem={({item})=>(
<Card>
<TouchableOpacity onPress={(_item)=>{handlePress(item)}}>
<View style={styles.mealItem}>
<Image style={{width:300,height:150}} resizeMode={'contain'} source={item.img} marginLeft={30}/>
<View style={styles.descrip}>
<Text style={styles.rating}>{item.title}</Text>
<Text style={styles.name}>{item.body}</Text>
</View>
</View>
</TouchableOpacity>
</Card>
)}
/>
<Modal
transparent={true}
visible={this.state.show}
>
<View style={styles.modal}>
<View style={styles.inModal}>
<Button title='End' onPress={()=>{this.setState({show:false})}}/>
</View>
</View>
</Modal>
</View>
);}
}
this is the code I'm currently working on I want the 'meal_data' in 'handlePress' to be displayed inside my modal 'meal_data' is the selected item from the flat list .
<Modal
transparent={true}
visible={this.state.show}
>
<View style={styles.modal}>
<View style={styles.inModal}>
<Button title='End' onPress={()=>{this.setState({show:false})}}/>
</View>
</View>
</Modal>
I want to display it in here above the button
Change these lines of code:
Change: <TouchableOpacity onPress={(_item)=>{handlePress(item)}}>
To
<TouchableOpacity onPress={() => this.handlePress(item)}>
Delete this code inside render():
const handlePress = (meal_data) =>{
this.setState({show: true});
this.setState({selectedMeal:meal_data});
console.log(meal_data)
}
And put this code above render() medthod instead:
handlePress = (meal_data) =>{
this.setState({show: true, selectedMeal: meal_data});
console.log(meal_data)
}
Inside state
this.state = {
loaded:false,
show:false,
key:''
selectedMeal: null // Add this property
}}
After that, you'll be able to access selectedMeal inside your Modal.
Put this code inside the Modal (or somewhere else)
{this.state.selectedMeal && (
<View>
<Text>{this.state.selectedMeal.title}</Text>
</View>
)}
First of declare your handlePress outside of render method. Other thing is that this.setState() is Async so, first set you data then show the modal. Your final code should look like this :
import React, { Component } from 'react';
import { View, Text, Image, StyleSheet, Modal, Button } from 'react-native';
import { FlatList, TouchableOpacity, ScrollView } from 'react-native-gesture-handler';
import Card from '../shared/card';
import { AppLoading } from 'expo';
import * as Font from 'expo-font';
export default class MealSearch extends Component {
constructor(props) {
super(props)
this.state = {
loaded: false,
show: false,
key: ''
}
}
handlePress = (meal_data) => {
this.setState({ selectedMeal: meal_data }, () => {
this.setState({ show: true });
});
console.log(meal_data)
}
render() {
const meal = [
{ title: 'My hero Academia', img: { uri: 'https://i.cdn.turner.com/adultswim/big/img/2018/05/10/MHA_Header.png' }, body: 'Rating : 4.5/5', id: '1' },
{ title: 'Naruto', img: { uri: 'https://store-images.s-microsoft.com/image/apps.15041.71343510227343465.377174a9-abc8-4da3-aaa6-8874fdb9e2f5.00fc0a9e-295e-40ca-a391-58ed9f83e9a0?mode=scale&q=90&h=1080&w=1920&background=%23FFFFFF' }, body: 'Rating : 5/5', id: '2' },
{ title: 'Attack On Titan', img: { uri: 'https://www.denofgeek.com/wp-content/uploads/2013/12/attack-on-titan-main.jpg?fit=640%2C380' }, body: 'Rating : 4.5/5', id: '3' },
{ title: 'Fate: Unlimited Blade Works', img: { uri: 'https://derf9v1xhwwx1.cloudfront.net/image/upload/c_fill,q_60,h_750,w_1920/oth/FunimationStoreFront/2066564/Japanese/2066564_Japanese_ShowDetailHeaderDesktop_496a6d81-27db-e911-82a8-dd291e252010.jpg' }, body: 'Rating : 4.5/5', id: '4' }
]
return (
<View style={styles.view} >
<FlatList
keyExtractor={item => item.id}
data={meal}
renderItem={({ item }) => (
<Card>
<TouchableOpacity onPress={() => { this.handlePress(item) }}>
<View style={styles.mealItem}>
<Image style={{ width: 300, height: 150 }} resizeMode={'contain'} source={item.img} marginLeft={30} />
<View style={styles.descrip}>
<Text style={styles.rating}>{item.title}</Text>
<Text style={styles.name}>{item.body}</Text>
</View>
</View>
</TouchableOpacity>
</Card>
)}
/>
<Modal
transparent={true}
visible={this.state.show}
>
<View style={styles.modal}>
<View style={styles.inModal}>
<Button title='End' onPress={() => { this.setState({ show: false }) }} />
</View>
</View>
</Modal>
</View>
);
}
}
I'm trying to move through screens using React Navigation, the problem lies in the nested return that i use to dynamically render a set of items and doesn't let me use an arrow function to directly navigate, so i have to implement this on a function. My question here is, how do i do that? As far as my internet research went you can only push a new screen after a dialog alert shows up, i don't want that.
I'm attaching the code:
var Dimensions = require('Dimensions');
var {width,height} = Dimensions.get('window');
import React, {Component} from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity,
Image
} from 'react-native';
import Pie from 'react-native-pie';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import NaviBarView from './../Commons/NaviBar'
import actions from '../../Redux/actions'
class Main extends Component {
constructor(props){
super(props);
this.state={
cargando:true,
cryptoCurrencyValues:{}
}
this.onNextPress = this.onNextPress.bind(this);
this.renderItems = this.renderItems.bind(this);
}
static getDerivedStateFromProps(nextProps,prevState){
console.warn('Positivo', Object.keys(nextProps.cryptoCurrencyValues).length)
if (Object.keys(nextProps.cryptoCurrencyValues).length !== 0){
}else{
console.warn('Negativo')
}
return null;
}
onNextPress(){
**//HERE I WANT TO CALL NAVIGATE TO MOVE TO ANOTHER SCREEN**
}
componentDidMount(){
console.warn('esto una vez')
this.props.actions.getCryptoValues();
this.setState({cargando:true})
}
renderItems(){
var self = this;
return listData.map(function(cryptoValue,i){
return(
<View style={styles.itemContainer} key={i}>
<View style={{alignSelf:'center',backgroundColor:'transparent', marginLeft:10}}>
<Image source={cryptoValue.img} style={{width:width*0.095, height:height*0.050}} resizeMode={'stretch'}/>
</View>
<View style={{marginLeft:10}}>
<View style={{alignSelf:'flex-start',marginTop:15}}>
<Text style={{color:'#ffffff',fontSize:18,fontWeight: 'bold'}}>{cryptoValue.name}</Text>
</View>
<View style={{alignSelf:'flex-start',marginBottom:10}}>
<Text style={{color:'#6e6e6e',fontSize:18}}>{cryptoValue.desc}</Text>
</View>
</View>
<View style={{marginLeft:40}}>
<View style={{alignSelf:'flex-start',marginTop:15}}>
<Text style={{color:'#ffffff',fontSize:18}}>{cryptoValue.price}</Text>
</View>
<View style={{alignSelf:'flex-start',marginBottom:10}}>
<Text style={{color:'#6e6e6e',fontSize:18}}>{cryptoValue.currency}</Text>
</View>
</View>
<View style={{alignSelf:'center',backgroundColor:'transparent', marginLeft:50}}>
<TouchableOpacity onPress={() => self.onNextPress()} style={{alignSelf:'center',backgroundColor:'transparent'}}>
<Image source={require('./../../img/next.png')} style={{width:width*0.035, height:height*0.032}} resizeMode={'stretch'}/>
</TouchableOpacity>
</View>
</View>
);
});
}
render(){
return(
<View style={styles.container}>
<View>
<NaviBarView/>
</View>
<View style={styles.cardContainer}>
<View style={{marginTop:10,flexDirection: 'row',marginTop:10,marginLeft:10,alignItems:'stretch'}}>
<Image source={require('./../../img/pie-chart.png')} resizeMode={'stretch'} style={{width:width*0.095, height:height*0.055}}/>
<Text style={{fontSize:20,color:'#ffffff',fontWeight:'bold',marginLeft:15,alignSelf:'center'}}>STATUS</Text>
<TouchableOpacity style={{marginLeft:230,alignSelf:'center'}}>
<Image source={require('./../../img/reload.png')} resizeMode={'stretch'} style={{width:width*0.065, height:height*0.035}}/>
</TouchableOpacity>
</View>
<View style={{alignSelf:'flex-start',marginTop:50}}>
<Pie
radius={100}
innerRadius={97}
series={[10, 20, 30, 40]}
colors={['#f00', '#0f0', '#00f', '#ff0']}
/>
</View>
</View>
{this.renderItems()}
</View>
);
}
}
const listData = [
{_id:1,name:'Bitcoin',desc:'Billetera BTC',price:'$141,403.22',currency:'BTC: $11.673,50',img:require('./../../img/bitcoin.png')},
{_id:2,name:'Ethereum',desc:'Billetera ETH',price:'$20200,50',currency:'ETH: $863,40',img:require('./../../img/ethereum.png')},
{_id:3,name:'NEO',desc:'Billetera NEO',price:'$40.401',currency:'NEO: $118,02',img:require('./../../img/neo.png')},
];
const styles = new StyleSheet.create({
container:{
flex:1,
backgroundColor: '#0d0d0d',
flexDirection: 'column',
position:'relative',
},
cardContainer:{
backgroundColor:'#1a1a1a',
marginTop: 7,
marginBottom:7,
marginLeft:7,
marginRight:7,
height:height*0.50,
width:width,
justifyContent: 'flex-start'
},
itemContainer:{
flexDirection: 'row',
backgroundColor:'#1a1a1a',
width:width,
height:height*0.115,
marginLeft:7,
marginRight:7,
marginBottom:7,
justifyContent: 'flex-start'
},
})
function mapStateToProps (state,props) {
return {cryptoCurrencyValues: state.cryptocurrencyValues,
}
}
function mapDispatchToProps (dispatch) {
return {
actions: bindActionCreators(actions, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Main);
You can use Stack Navigator here which is very easy to navigate from one screen to another and as well as in function too...
First.
Install library :-
npm install --save react-navigation
Then use it in your class by using import :-
import {StackNavigator} from 'react-navigation';
export that class
export default Project = StackNavigator(
{
xyz: { screen: xyz },
});
After that navigating using function:-
onNextPress=()=>
{
this.props.navigation.navigate('xyz');
}
Hope.it will helps you .
Thanx!
I was not passing the navigation prop when defining my RootStack:
import React, {Component} from 'react'
import {
AppRegistry,
StyleSheet,
Text,
View,
} from 'react-native';
import createStore from './../../Redux/store';
import {StackNavigator} from 'react-navigation';
import { Provider } from 'react-redux';
import MainView from '../Main/Main';
import MainSecondLvlView from '../Main/MainSecondLvl';
import BalanceView from './../Charts/BalanceView'
import MenuView from './Menu'
const store = createStore();
const RootStack = StackNavigator({
Main: { screen: MainView },
MainSecondLvl: { screen: MainSecondLvlView},
Menu:{ screen: MenuView }
},
{
initialRouteName: 'Main',
headerMode: 'none',
});
export default class App extends Component {
render(){
return(
<Provider store={store}>
<RootStack navigation={this.props.navigation}/>
</Provider>
);
}
}
I'm integrating DrawerNavigator of 'react-navigation' to my project as this document. But when I run the project it always get this error when click on the Button:
TypeError: undefined is not an object (evaluating
'this.props.navigation.navigate')
And when I swipe from left to right, nothing happen, no drawer open.
I've check this.props and it's always log empty {} in console.
I tried many solutions but it's still not working.
calculator.js
export default class Calculator extends Component {
constructor(props) {
super(props);
}
static navigationOptions = {
drawerLabel: 'Calculator',
drawerIcon: ({ tintColor }) => (
<Image
source={require('./../../res/images/icon_calculator.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
};
render() {
return (
<View style={styles.container}>
<View>
<Text style={styles.title}>Tip Calculator</Text>
</View>
<Button
onPress={() => this.props.navigation.navigate("SettingsScreen")}
title="Go to settings"
/>
</View>
);
}
}
module.exports = Calculator;
settings.js
export default class Settings extends Component {
constructor(props) {
super(props);
}
static navigationOptions = {
drawerLabel: 'Settings',
drawerIcon: ({ tintColor }) => (
<Image
source={require('./../../res/images/icon_settings.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
};
render() {
return (
<View style={styles.container}>
<Text>Settings</Text>
<Button
onPress={() => this.props.navigation.goBack()}
title="Go back home"
/>
</View>
);
}
}
module.exports = Settings;
navigation.js
import {
DrawerNavigator
} from 'react-navigation';
import Calculator from './../components/calculator/calculator.js';
import Settings from './../components/settings/settings.js';
const RootDrawer = DrawerNavigator({
CalculatorScreen: {
path: '/',
screen: Calculator
},
SettingsScreen: {
path: '/sent',
screen: Settings
}
}, {
initialRouteName: 'CalculatorScreen',
drawerPosition: 'left'
});
export default RootDrawer;
App.js
export default class App extends Component<{}> {
render() {
return (
<Calculator/>
);
}
}
index.js
import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('rn_tip_calculator', () => App);
Do I have to use StackNavigator with DrawerNavigator, or am I missed something in config?
Full source code, it's only a simple example project, please have a look: https://github.com/HCMUS-IceTeaViet-SE/rn_tip_calculator
Any help will be appreciated. Thanks!
You can use dispatch api https://reactnavigation.org/docs/navigators/navigation-actions
1) import navigation actions
import { NavigationActions } from 'react-navigation'
2) dispatch navigation action:
const navigateAction = NavigationActions.navigate({
routeName: 'SettingsScreen',
params: {},
})
this.props.navigation.dispatch(navigateAction)
I'm pretty new to React-Native but sometimes this also happens to me.
I'm using Redux and stack navigator.... but here is my working example...
import { StackNavigator } from 'react-navigation'
import { Animated, Easing } from 'react-native'
import LoginScreen from '../Containers/LoginScreen'
import LaunchScreen from '../Containers/LaunchScreen'
import HomeScreen from '../Containers/HomeScreen'
import SignUpScreen from '../Containers/SignUpScreen'
import SettingsScreen from '../Containers/SettingsScreen'
import VehicleCreateScreen from '../Containers/VehicleCreateScreen'
import styles from './Styles/NavigationStyles'
// Manifest of possible screens
const PrimaryNav = StackNavigator({
LoginScreen: { screen: LoginScreen },
LaunchScreen: { screen: LaunchScreen },
HomeScreen: { screen: HomeScreen },
SignUpScreen: { screen: SignUpScreen },
SettingsScreen: { screen: SettingsScreen },
VehicleCreateScreen: { screen: VehicleCreateScreen }
}, {
// Default config for all screens
headerMode: 'none',
initialRouteName: 'LaunchScreen',
navigationOptions: {
headerStyle: styles.header
},
transitionSpec: {
duration: 0,
timing: Animated.timing,
easing: Easing.step0,
},
},
)
export default PrimaryNav
And then from a component not connected to REDUX
import React, { Component } from 'react';
import { Container, Content, List, ListItem, Icon, Text, Button, Left, Right, Badge } from 'native-base';
import { Image } from 'react-native'
import styles from './Styles/SideBarStyle';
// import backgroundImage from '../Images/vw.jpg'
const backgroundImage = require("../Images/vw.jpg");
const drawerImage = require("../Images/dirtyHandsDark.jpg");
export default class SideBar extends Component {
constructor(props) {
super(props);
}
render() {
// *********** HERE WE DECLARE AN ARRAY TO RENDER LISTS FROM. THIS COULD ALSO BE LIST OF BIKES FROM STORE.. ***********
const datas = [
{
name: "Home",
route: "HomeScreen",
icon: "settings",
bg: "#C5F442",
},
{
name: "Repair",
route: "HomeScreen",
icon: "settings",
bg: "#C5F442",
},
{
name: "My Profile",
route: "SettingsScreen",
icon: "settings",
bg: "#C5F442",
},
];
return (
<Container>
<Content bounces={false} style={{ flex: 1, backgroundColor: "#fff", top: -1 }}>
<Image source={backgroundImage} style={styles.drawerCover}>
<Image square style={styles.drawerImage} source={drawerImage} />
</Image>
<List
dataArray={datas}
renderRow={data =>
// *********** CREATE NEW LIST ITEM ON CLICK NAVIGATE TO APPROPRIATE LISTITEM.SCREEN ***********
<ListItem button noBorder onPress={() => this.props.navigation.navigate(data.route)}>
<Left>
<Icon active name={data.icon} style={{ color: "#777", fontSize: 26, width: 30 }} />
<Text style={styles.text}>
{data.name}
</Text>
</Left>
{data.types &&
<Right style={{ flex: 1 }}>
<Badge
style={{
borderRadius: 3,
height: 25,
width: 72,
backgroundColor: data.bg,
}}
>
<Text style={styles.badgeText}>{`${data.types} Types`}</Text>
</Badge>
</Right>}
</ListItem>}
/>
</Content>
</Container>
);
}
}
You can see I reference this.props.navigation.navigate no problem.
Heres my repo for reference.
https://github.com/GavinThomas1192/motoMechanicMeeKanic/tree/master/App
This happen because I don't "connect" my DrawerNavigator to my app.
There is 2 ways to achieve this:
First way: register DrawerNavigator as app root component. In index.js change:
from AppRegistry.registerComponent('rn_tip_calculator', () => App);
to AppRegistry.registerComponent('rn_tip_calculator', () => RootDrawer);
So you could delete App.js because it's useless now.
Second way: Keep register App component (in App.js) as app root component. Then put inside App component to "connect" DrawerNavigator to the app.
export default class App extends Component<{}> {
render() {
return (
<RootDrawer/>
);
}
}
The document say nothing about how to connect the navigator to the app, nothing about register component or put navigator inside root component. This drive newbie like me mad!