Related
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 just started learning and practicing React Native and I have run into the first problem that I cant seem to solve by myself.
I have the following code, which is very simple, but the Alert.alert() does not work when I run it on the web. if I click the button nothing happens, however, when i click the button on an iOS or android simulator it works fine.
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, Button, View, Alert } from 'react-native';
export default function App() {
return (
<View style={styles.container}>
<Text style={styles.headerStyle} >Practice App</Text>
<Text style={{padding: 10}}>Open up App.js to start working on your app!</Text>
<Button
onPress={() => alert('Hello, Nice To Meet You :)')}
title="Greet Me"
/>
<StatusBar style="auto" />
</View>
);
}
I also know that alert() works on all three devices, however, I want to understand why Alert.alert() only works for iOS and Android.
My question is more so for understanding rather than finding a solution. Is the only solution to use alert(), or am I implementing Alert.alert() in the wrong way?
This workaround basically imitates react-native's Alert behavior with browsers' window.confirm method:
# alert.js
import { Alert, Platform } from 'react-native'
const alertPolyfill = (title, description, options, extra) => {
const result = window.confirm([title, description].filter(Boolean).join('\n'))
if (result) {
const confirmOption = options.find(({ style }) => style !== 'cancel')
confirmOption && confirmOption.onPress()
} else {
const cancelOption = options.find(({ style }) => style === 'cancel')
cancelOption && cancelOption.onPress()
}
}
const alert = Platform.OS === 'web' ? alertPolyfill : Alert.alert
export default alert
Usage:
Before:
import { Alert } from 'react-native'
Alert.alert(...)
After:
import alert from './alert'
alert(...)
Source & Credits: https://github.com/necolas/react-native-web/issues/1026#issuecomment-679102691
React Native is an open-source mobile application framework for Android, iOS and Web but there is not an Alert Component for Web but I have found a package which will provide you solutation. That is it to install package
npm i react-native-awesome-alerts
This example will help you
import React from "react";
import { StyleSheet, Text, View, TouchableOpacity } from "react-native";
import Alert from "react-native-awesome-alerts";
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { showAlert: false };
}
showAlert = () => {
this.setState({
showAlert: true,
});
};
hideAlert = () => {
this.setState({
showAlert: false,
});
};
render() {
const { showAlert } = this.state;
return (
<View style={styles.container}>
<Text>Practice App</Text>
<Text style={{ padding: 10 }}>
Open up App.js to start working on your app!
</Text>
<TouchableOpacity
onPress={() => {
this.showAlert();
}}
>
<View style={styles.button}>
<Text style={styles.text}>Greet Me</Text>
</View>
</TouchableOpacity>
<Alert
show={showAlert}
message="Hello, Nice To Meet You :"
closeOnTouchOutside={true}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: "#fff",
},
button: {
margin: 10,
paddingHorizontal: 10,
paddingVertical: 7,
borderRadius: 5,
backgroundColor: "#AEDEF4",
},
text: {
color: "#fff",
fontSize: 15,
},
});
I need to put a Camera ("expo-camera") view inside a horizontal viewPager ("#react-native-community/viewpager").
I can't get it to work.
I was able to place other components with no problem, and I was able to show the Camera as a stand alone view.
I'm still a beginner.
Is this possible?
If so, can someone make a simple template of these two components together please?
ViewPager:
import React from "react";
import ViewPager from "#react-native-community/viewpager";
import Record from "../../components/Record";
import { View } from "react-native";
const Home: React.FC = () => {
return (
<ViewPager
onPageSelected={(event) => {
//Nothing yet
}}
style={{ flex: 1, backgroundColor: "#000" }}
orientation="horizontal"
scrollEnabled={true}
>
<View style={{ flex: 1, backgroundColor: "#f54242" }} />
<Record isFeed={false} />
</ViewPager>
);
};
export default Home;
Camera:
import React, { useEffect } from "react";
import { Camera } from "expo-camera";
import { View, Text, StatusBar } from "react-native";
const Record: React.FC = () => {
const [hasPermission, setHasPermission] = useState<boolean | null>(null);
useEffect(() => {
async function permission(): Promise<void> {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === "granted");
StatusBar.setHidden(true);
}
permission();
}, []);
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<Camera type={Camera.Constants.Type.back}/>
);
};
export default Record;
Appreciate all the help I can get.
App.js:
import React, { Component } from 'react';
import {View,Text} from 'react-native';
import { createDrawerNavigator } from 'react-navigation-drawer';
import {createAppContainer} from 'react-navigation';
import Epics from './screens/tmp';
import Pager from './screens/Pager';
const DrawerNavigator = createDrawerNavigator({
Home: {screen: Epics},
Page: {screen: Pager}
},{initialRouteName: 'Home'});
const Stack = createAppContainer(DrawerNavigator);
export default class App extends Component {
render() {
return <Stack />;
}
}
Trying to navigate to a screen through a custom component:
import { ActivityIndicator, Image, StyleSheet, View, TouchableHighlight } from 'react-native';
import PropTypes from 'prop-types';
import React from 'react';
import { useNavigation } from 'react-navigation-hooks';
import AuthorRow from './AuthorRow';
export default class Card extends React.Component {
static propTypes = {
fullname: PropTypes.string.isRequired,
image: Image.propTypes.source.isRequired,
linkText: PropTypes.string.isRequired,
onPressLinkText: PropTypes.func.isRequired,
epicId: PropTypes.string.isRequired,
};
state = {
loading: true,
};
getNav(){
return useNavigation();
}
handleLoad = () => {
this.setState({ loading: false });
};
render() {
const { fullname, image, linkText, onPressLinkText, epicId, prop } = this.props;
const { loading } = this.state;
return (
<View>
<AuthorRow
fullname={fullname}
linkText={linkText}
onPressLinkText={onPressLinkText}
/>
<TouchableHighlight onPress={() => this.getNav().navigate('Pager')} underlayColor="white">
<View style={styles.image}>
{loading && (
<ActivityIndicator style={StyleSheet.absoluteFill} size={'large'} />
)}
<Image
style={StyleSheet.absoluteFill}
source={image}
onLoad={this.handleLoad}
/>
</View>
</TouchableHighlight>
</View>
);
}
}
const styles = StyleSheet.create({
image: {
aspectRatio: 1,
backgroundColor: 'rgba(0,0,0,0.02)',
},
});
From above code, trying to navigate using:
import { useNavigation } from 'react-navigation-hooks';
getNav(){ return useNavigation(); }
this.getNav().navigate('Pager')
It errors our stating: Invariant Violation: Invalid hook call. Hooks can only be called inside of the body of a function component.
How do I navigate using "useNavigation()" or how do I get "this.props.navigation" reference in a component? (I am new to React Native, please help me understand)
Update
I tried using "this.props.navigation" and it gives me undefined error:
#sayog you are breaking the rule of hook brother.
Could you try this?
const [loading, setLoading] = useState(false);
const navigation = useNavigation();
make sure you put it after your state declaration
Note: Dont' use class component for Hook. use Functional Component for hook
//In Card component remove this
//import { useNavigation } from 'react-navigation-hooks';
//Add this line
import {withNavigation} from 'react-navigation';
class Card extends React.Component {
static propTypes = {
fullname: PropTypes.string.isRequired,
image: Image.propTypes.source.isRequired,
linkText: PropTypes.string.isRequired,
onPressLinkText: PropTypes.func.isRequired,
epicId: PropTypes.string.isRequired,
};
state = {
loading: true,
};
//Remove this
// getNav(){
// return useNavigation();
//}
handleLoad = () => {
this.setState({ loading: false });
};
render() {
const { fullname, image, linkText, onPressLinkText, epicId, prop } = this.props;
const { loading } = this.state;
return (
<View>
<AuthorRow
fullname={fullname}
linkText={linkText}
onPressLinkText={onPressLinkText}
/>
<TouchableHighlight onPress={() =>
//Make change like this
this.props.navigation.navigate('Pager')} underlayColor="white">
<View style={styles.image}>
{loading && (
<ActivityIndicator style={StyleSheet.absoluteFill} size={'large'} />
)}
<Image
style={StyleSheet.absoluteFill}
source={image}
onLoad={this.handleLoad}
/>
</View>
</TouchableHighlight>
</View>
);
}
}
const styles = StyleSheet.create({
image: {
aspectRatio: 1,
backgroundColor: 'rgba(0,0,0,0.02)',
},
});
//Make change like this
export default withNavigation(Card)
here is your mistake
mistake
onPress={() => this.getNav().navigate('Pager')
replace with
onPress={() => this.props.navigation.navigate('Pager')
here is the example
https://reactnavigation.org/docs/navigating/
https://medium.com/#marizu_makozi/navigating-between-screens-or-activities-using-react-navigation-library-68d57657d81
Another example code
class FirstScreen extends React.Component {
static navigationOptions = {
title: 'First',
}
componentDidMount(){
const {navigate} = this.props.navigation;
navigate('Second');
fetch('http://apiserver').then( (response) => {
navigate('Second');
});
}
render() {
return (
<AppLogo />
);
}
}
const AppNavigator = StackNavigator({
First: {
screen: FirstScreen,
},
Second: {
screen: SecondScreen,
},
});
You cannot use hooks inside Class component convert your class component to a functional component or use navigation object for navigations by passing navigation props to your component this.props.navigation.navigate('screenName')
I am trying to navigate user to next screen when user click on list item. I am trying to make use of Navigator in this , i am newbie to react , there is Redux and Flux two different architecture as i am not every much good in react so i am little confuse with there working.We can navigate user by using Navigator and also by using Action. Here is my class :-
ERROR i am Getting is :- undefined is not a function(evaluating '_this4.goDetailPage(rowData)')
Today.js
import React, { Component } from 'react';
import {
StyleSheet,
Text,
} from 'react-native';
import {FeedStack} from './movielistdeatilrouter';
export default class TodayView extends Component {
constructor(props , context) {
super(props , context);
}
render() {
return (
<FeedStack />
);
}
}
movielistdeatilrouter.js : -
import React from 'react';
import {StackNavigator } from 'react-navigation';
import MovieDeatilScreen from './MovieDeatilScreen';
import Movielisting from './movielisting';
export const FeedStack = StackNavigator({
Movielisting: {
screen: Movielisting,
navigationOptions: {
title: 'Movielisting',
},
},
MovieDeatilScreen: {
screen: MovieDeatilScreen,
navigationOptions: ({ navigation }) => ({
title: 'MovieDeatilScreen',
}),
},
});
movielistiing.js :-
import React, { Component } from 'react';
import { StatusBar } from 'react-native'
import { StackNavigator } from 'react-navigation';
import { NavigationActions } from 'react-navigation';
import { Actions, ActionConst } from 'react-native-router-flux';
import home from '../images/home.png';
import MovieDeatilScreen from './MovieDeatilScreen'
const { width: viewportWidth, height: viewportHeight } = Dimensions.get('window');
import {
StyleSheet,
Text,
Image,
View,
AsyncStorage,
TouchableOpacity,
TouchableHighlight,
Dimensions,
ListView
} from 'react-native';
const uri = 'http://csswrap.com/wp-content/uploads/2015/03/showmenu.png';
export default class Movielisting extends Component {
constructor(props) {
super(props);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
moviesData: ds.cloneWithRows([]),
};
}
componentDidMount() {
this.fetchMoviesData();
}
fetchMoviesData() {
var url = 'http://api.themoviedb.org/3/movie/now_playing?api_key=17e62b78e65bd6b35f038505c1eec409';
fetch(url)
.then(response => response.json())
.then(jsonData => {
this.setState({
moviesData: this.state.moviesData.cloneWithRows(jsonData.results),
});
})
.catch( error => console.log('Error fetching: ' + error) );
}
render() {
return (
<View style={styles.container}>
<ListView
dataSource={this.state.moviesData}
renderRow={this.renderRow}
enableEmptySections={true}
style={styles.ListViewcontainer}
/>
</View>
);
}
renderRow(rowData){
return (
<View style={styles.thumb} >
<TouchableOpacity onPress={() => this.goDeatilPage(rowData)}>
<Image
source={{uri:'https://image.tmdb.org/t/p/w500_and_h281_bestv2/'+rowData.poster_path}}
resizeMode="cover"
style={styles.img} />
<Text style={styles.txt}>{rowData.title} (Rating: {Math.round( rowData.vote_average * 10 ) / 10})</Text>
</TouchableOpacity>
</View>
);
}
goDeatilPage = (rowData) => {
alert('hi');
AsyncStorage.setItem('moviesData', JSON.stringify(rowData));
this.props.navigation.navigate('MovieDeatilScreen');
};
}
const styles = StyleSheet.create({
container: {
position:'relative',
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},action: {
flex: 0.4,
},thumb: {
backgroundColor: '#ffffff',
marginBottom: 5,
elevation: 1
},
img: {
height: 300
},
txt: {
margin: 10,
fontSize: 16,
textAlign: 'left'
},ListViewcontainer:{
marginTop:50,
bottom: 50,
}
});
Index.android.js :-
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
StatusBar,
View
} from 'react-native';
import App from './app';
import DrawerMenu from './Drawer/drawer-toolbar-android';
import BookmarkView from './Pages/bookmark';
import CalendarView from './Pages/calendar';
import ClientView from './Pages/client';
import InfoView from './Pages/info';
import SettingsView from './Pages/setting';
import { DrawerNavigator, StackNavigator } from 'react-navigation';
const stackNavigator = StackNavigator({
Info: { screen: InfoView },
Settings: {screen: SettingsView },
Bookmark: {screen: BookmarkView },
Calendar: {screen: CalendarView},
Client: {screen: ClientView},
}, {
headerMode: 'none'
});
const easyRNRoute = DrawerNavigator({
Home: {
screen: App,
},
Stack: {
screen: stackNavigator
}
}, {
contentComponent: DrawerMenu,
contentOptions: {
activeTintColor: '#e91e63',
style: {
flex: 1,
paddingTop: 15,
}
}
});
AppRegistry.registerComponent('flightbot', () => easyRNRoute);
App.js class :-
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
StatusBar,
View
} from 'react-native';
import { Navigator, NativeModules } from 'react-native';
import { COLOR, ThemeProvider } from 'react-native-material-ui';
import { Toolbar, BottomNavigation, Icon } from 'react-native-material-ui';
import Container from './Container';
import { TabRouter } from 'react-navigation';
import TodayView from './Contents/today';
import ProfileView from './Contents/profile';
import MapView from './Contents/map';
import ChatView from './Contents/chat';
const uiTheme = {
palette: {
primaryColor: COLOR.green500,
accentColor: COLOR.pink500,
},
toolbar: {
container: {
height: 70,
paddingTop: 20
}
}
}
const TabRoute = TabRouter({
Today: { screen: TodayView },
Profile: { screen: ProfileView },
Map: { screen: MapView },
Chat: {screen: ChatView}
}, {
initialRouteName: 'Today',
}
);
class TabContentNavigator extends Component {
constructor(props, context) {
super(props, context);
this.state = {
active: props.value.active,
};
}
//this method will not get called first time
componentWillReceiveProps(newProps){
this.setState({
active: newProps.value.active,
});
}
render() {
const Component = TabRoute.getComponentForRouteName(this.state.active);
return <Component/>;
}
}
export default class App extends Component {
constructor(props, context) {
super(props, context);
this.state = {
active: 'Today',
};
}
static navigationOptions = {
title: 'Menu',
};
navigate() {
this.props.navigation.navigate('DrawerOpen'); // open drawer
}
render() {
return (
<ThemeProvider uiTheme={uiTheme}>
<Container>
<StatusBar backgroundColor="rgba(0, 0, 0, 0.2)" translucent />
<Toolbar
leftElement="menu"
centerElement={this.state.active}
onLeftElementPress={() => this.navigate()}
/>
<TabContentNavigator value={this.state} key={this.state} />
<BottomNavigation active={this.state.active}
hidden={false}
style={{ container: { position: 'absolute', bottom: 0, left: 0, right: 0 } }}
>
<BottomNavigation.Action
key="Today"
icon="today"
label="Today"
onPress={() => this.setState({ active: 'Today' })}
/>
<BottomNavigation.Action
key="Profile"
icon="person"
label="Profile"
onPress={() => {
this.setState({ active: 'Profile' });
}}
/>
<BottomNavigation.Action
key="Map"
icon="map"
label="Map"
onPress={() => this.setState({ active: 'Map' })}
/>
<BottomNavigation.Action
key="Chat"
icon="chat"
label="Chat"
onPress={() => this.setState({ active: 'Chat' })}
/>
</BottomNavigation>
</Container>
</ThemeProvider>
);
}
}
i am trying my level best to solve this , its almost 3 days today i am looking for solution that how i can do this , i just want to open a new Screen on click on list item. Can any one tell me how to do that.I will be very Grateful if some one let me know the way to navigate to next screen.
ScreenShot of my Error :-
Thanks!!!
Using "React Navigation" should help you to do the trick.
For more information, you can find it here: https://reactnavigation.org
Cheers,
====== UPDATE ======
I believe the way you set up the Today component is incorrect, and also your question is unclear, it took me a while to understand what you're wanting to do.
Anyway, Today component should be a StackNavigator if you want to open a detail screen from it, and it will control 2 screens (ListScreen and DetailScreen):
const TodayView = StackNavigator({
List: {
screen: ListScreen,
},
Detail: {
screen: DetailScreen,
},
});
Then setup your screens like this:
class ListScreen extends Component {
static navigationOptions = {
title: 'List',
}
constructor(props , context) {
super(props , context);
this.goToDetailScreen = this.goToDetailScreen.bind(this);
}
goToDetailScreen() {
this.props.navigation.navigate('Detail');
}
render() {
return (
<TouchableOpacity onPress={() => this.goToDetailScreen()}>
<Text>GO TO DETAIL</Text>
</TouchableOpacity>
);
}
}
class DetailScreen extends Component {
static navigationOptions = {
title: 'Detail',
}
render() {
return (
<TouchableOpacity onPress={() => this.props.navigation.goBack()}>
<Text>BACK TO LIST SCREEN</Text>
</TouchableOpacity>
);
}
}
There is an example calling "StacksInTabs" in their Github repo, that you might want to take a look at it: https://github.com/react-community/react-navigation/blob/master/examples/NavigationPlayground/js/StacksInTabs.js
Cheers,
Finally it works , this is how i do following change in code . :-
<View style={styles.container}>
<ListView
dataSource={this.state.moviesData}
renderRow={this.renderRow.bind(this)}
enableEmptySections={true}
style={styles.ListViewcontainer}
/>
</View>
I just added .bind(this) function to renderRow.
Rest is Same :-
renderRow(rowData){
return (
<View style={styles.thumb} >
<TouchableOpacity onPress={()=>this.goDeatilPage(rowData)}>
<Image
source={{uri:'https://image.tmdb.org/t/p/w500_and_h281_bestv2/'+rowData.poster_path}}
resizeMode="cover"
style={styles.img} />
<Text style={styles.txt}>{rowData.title} (Rating: {Math.round( rowData.vote_average * 10 ) / 10})</Text>
</TouchableOpacity>
</View>
);
}
goDeatilPage = (rowData) => {
alert('hi');
AsyncStorage.setItem('moviesData', JSON.stringify(rowData));
this.props.navigation.navigate('MovieDeatilScreen');
}
Thanks #Goon for your Time i highly Appreciate your effort. Thank you Brother.
Use React Navigation for navigate screen, it is very Easy-to-Use,
Create 3 class in react native
defined navigator class
2.first screen
3.navigate screen
1.Basic.js
import {
StackNavigator,
} from 'react-navigation';
const BasicApp = StackNavigator({
Main: {screen: Movielistiing},
Detail: {screen: Movielistdeatilrouter},
});
module.exports = BasicApp;
2.Movielistiing.js
class Movielistiing extends React.Component {
static navigationOptions = {
title: 'Welcome',
};
render() {
const { navigate } = this.props.navigation;
return (
<Button
title="Go to movie detail"
onPress={() =>
navigate('Detail', { name: 'Jane' })
}
/>
);
}
}
3.Movielistdeatilrouter.js
class Movielistdeatilrouter extends React.Component {
static navigationOptions = ({navigation}) => ({
title: navigation.state.params.name,
});
render() {
const { goBack } = this.props.navigation;
return (
<Button
title="Go back"
onPress={() => goBack()}
/>
);
}
}