I have a flatlist of movies when a user clicks on it, it passes param to movie details screen and movie detail is shown then that screen has flatlist of similar movies when user selects any of it, basically new params should be passed to movie details screen but no, it is just working as if i am tapping on back button....
onPress={() =>
this.props.navigation.navigate('MovieDetails', {
selectedItem: item,
})
} // Passing params to movie details screen
console.log(this.props.navigation.getParam('selectedItem')) //receiving params in movie details screen
Check this below example. Hope this will help you.
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ fontSize: 20, marginBottom: 10 }}>Home Screen</Text>
<Button
title="Go to Details"
onPress={() =>
this.props.navigation.navigate('Details', {
name: 'this params from homescreen',
})
}
/>
</View>
);
}
}
class DetailsScreen extends React.Component {
render() {
console.log('screen', this.props.navigation.state);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ fontSize: 20, marginBottom: 10 }}>
{this.props.navigation.state.params.name}
</Text>
<Button
title="Go back"
onPress={() => this.props.navigation.goBack()}
/>
</View>
);
}
}
const RootStack = createStackNavigator({
Home: HomeScreen,
Details: DetailsScreen,
});
export default createAppContainer(RootStack);
Feel free for doubts.
Related
I'm trying to update an app I've developed using react-navigation v4.
Using react-navigation v4 I could get the id using something like console.log(navigation.getParam('id'));
But when I tried the same after updating to v5 of react-navigation it shows me an error and I can't find the right way to get the param id
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
export default function ShowScreen({ navigation }) {
console.log(navigation.getParam('id'));
return (
<View style={styles.container}>
<Text>Show Screen</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});
The other screen where the id is located is it:
import React, { useContext } from 'react';
import { View, Text, StyleSheet, Button } from 'react-native';
import { FlatList, TouchableOpacity } from 'react-native-gesture-handler';
import { Context } from '../../context/BlogContext';
import Icon from 'react-native-vector-icons/Feather'
export default function IndexScreen({ navigation }) {
const { state, addBlogPost, deleteBlogPost } = useContext(Context);
return (
<View style={styles.container}>
<Button
title="Add Post"
onPress={addBlogPost}
/>
<FlatList
data={state}
keyExtractor={(blogPost) => blogPost.title}
renderItem={({ item }) => {
return (
<TouchableOpacity onPress={
() => navigation.navigate('ShowScreen',
{ id: item.id })}>
<View style={styles.row}>
<Text style={styles.title}>
{item.title} -
{item.id}
</Text>
<TouchableOpacity onPress={() => deleteBlogPost(item.id)}>
<Icon style={styles.icon}
name="trash"
/>
</TouchableOpacity>
</View>
</TouchableOpacity>
);
}}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 30,
justifyContent: 'center',
alignItems: 'center'
},
row: {
flexDirection: 'row',
justifyContent: 'space-between',
paddingHorizontal: 10,
paddingVertical: 20,
borderTopWidth: 1,
borderColor: '#333'
},
title: {
fontSize: 18
},
icon: {
fontSize: 24
}
});
You can get params using route.params in react navigation v5 more on that read here
just update your code to this
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
export default function ShowScreen({ navigation,route }) {
const {id} =route.params; //you will get id here via route
return (
<View style={styles.container}>
<Text>Show Screen</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
}
});
you can simply access your parameters like this
const id = this.props.route.params.id
inside this.props.route.params you will get all paramaters :)
I am completely new to React Native. So please apologize me for very naive questions.
I have a main screen which has a button. When the button is pressed I want to fetch data thru another component and display on the screen.
I have App.js
import React from 'react';
import { Button, View, Text } from 'react-native';
import { createAppContainer, createStackNavigator } from 'react-navigation'; // Version can be specified in package.json
import {getMovies} from "./fetchmenu.js";
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
<Button
title="Menu"
onPress={() => {
<getMovies /> // I want to display data as a result of button press
}}
/>
</View>
</View>
);
}
}
const AppContainer = createAppContainer(RootStack);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
And fetchmenu.js
import React from 'react';
import { FlatList, ActivityIndicator, Text, View } from 'react-native';
export default class getMovies extends React.Component {
constructor(props){
super(props);
this.state ={ isLoading: true}
}
componentDidMount(){
return fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson.movies,
}, function(){
});
})
.catch((error) =>{
console.error(error);
});
}
render(){
if(this.state.isLoading){
return(
<View style={{flex: 1, padding: 20}}>
<ActivityIndicator/>
</View>
)
}
return(
<View style={{flex: 1, paddingTop:20}}>
<FlatList
data={this.state.dataSource}
renderItem={({item}) => <Text>{item.title}, {item.releaseYear}</Text>}
keyExtractor={({id}, index) => id}
/>
</View>
);
}
}
How do I display the FlatList created by getMovies on HomeScreen
when the button is pressed?
In your HomeScreen set your state like this:
state={showMovies:false}
Then on Button click setState to {showMovies:true}. And in your render function in App.js:
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<View style={{ flex: 1, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }}>
<Button
title="Menu"
onPress={() => {
this.setState({showMovies:true});
}}
/>
{this.state.showMovies&&<GetMovies/>}
</View>
</View>
);
}
Since you are exporting getMovies class as default export (not named) do the same with importing:
WRONG: import {getMovies} from "./fetchmenu.js";
CORRECT: import GetMovies from "./fetchmenu.js";
I strongly recommend you to watch some tutorials before getting into real projects.
EDIT
As #Milore stated Component names in React must start with capital letter. See this for further information
constructor(props){
super(props);
this.state ={ isLoading: true}
}
I don't see dataSource in this.state but you are using
this.setState({
isLoading: false,
dataSource: responseJson.movies,
}, function(){
});
I am an beginner in react native.I want to display home page after logged in.I have install react-navigator using npm install and I have tried below code.
But I am getting below error, I tried to solve this. Still I have the error.
In App.js
//This is an example code for Bottom Navigation//
import React, { Component } from 'react';
//import react in our code.
import { Text, View, TouchableOpacity, StyleSheet } from 'react-native';
//import all the basic component we have used
import { createStackNavigator, createAppContainer } from 'react-navigation';
export default class App extends Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text style={{ marginTop: 50, fontSize: 25 }}>Setting!</Text>
<View
style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.navigation.navigate('Two')}>
<Text>Go to Home Tab</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.navigation.navigate('Two')}>
<Text>Open Detail Screen</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => this.props.navigation.navigate('Two')}>
<Text>Open Profile Screen</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
button: {
alignItems: 'center',
backgroundColor: '#DDDDDD',
padding: 10,
width: 300,
marginTop: 16,
},
});
Can anyone assist me to solve this?
You can do it as following:
import React from "react";
import { View, Text } from "react-native";
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen</Text>
</View>
);
}
}
class LoginScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Login Screen</Text>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
</View>
);
}
}
on App.js,
import React from 'react';
import { HomeScreen, LoginScreen } from '..'// should set the proper path.
const AppNavigator = createStackNavigator({
Login: LoginScreen,
Home: HomeScreen
});
const App = () => {
return <AppNavigator />;
}
export default App;
I am using stackNavigator in react native .my problem is I want to move to another screen using stack navigator.
app.js
const CartStack=createStackNavigator({
Header:Header,
Cart:Cart
)}
Const Root=createStackNavigator({
Home:Home,
Detail:Detail,
CartStack:CartStack,
)}
Home.js
render() {
return (
<Header/>
)}
The Header Will be show on both screens (Home and Detail)
in the header i created a cart button which i want to click on
it then will be open a Cart screen. But my code is not working.
Please correct my code.
The concept in Zayco's answer is absolutely correct.
But I figured out that this.props.navigation.navigate will be undefined in navigationOptions
Here is the working example of your requirement.
class Home extends React.Component {
static navigationOptions = ({navigation}) => ({
title: 'Home',
headerRight:(<Button title="Cart" onPress={() => navigation.navigate('Cart')}/>)
})
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Scree</Text>
<Button
title="Go to Details"
onPress={() => this.props.navigation.navigate('Details')}
/>
</View>
);
}
}
class Details extends React.Component {
static navigationOptions = ({navigation}) => ({
title: 'Details',
headerRight:(<Button title="Cart" onPress={() => navigation.navigate('Cart')}/>)
})
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details</Text>
</View>
);
}
}
class Cart extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Cart</Text>
</View>
);
}
}
const RootStack = createStackNavigator(
{
Home: Home,
Details: Details,
Cart:Cart
},
{
initialRouteName: 'Home',
}
);
This is taken from the React Navigation documentation
You have 3 screens: Home, Details and Cart. In the header of Home and Details you have a button that will take you to the Cart screen. I suggest you take a look at the Fundementals section of the documentation.
Here is the working Snack
import React from "react";
import { View, Text, Button } from "react-native";
import { createStackNavigator, createAppContainer } from "react-navigation";
class HomeScreen extends React.Component {
static navigationOptions = ({ navigation }) => ({
headerTitle: "Home",
headerRight: (
<Button
onPress={() => navigation.navigate('Cart')}
title="Cart"
color="blue"
/>
)
});
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen</Text>
<Button
onPress={() => this.props.navigation.navigate('Details')}
title="Go to details"
color="red"
/>
</View>
);
}
}
class DetailsScreen extends React.Component {
static navigationOptions = ({ navigation }) => ({
headerTitle: "Details",
headerRight: (
<Button
onPress={() => navigation.navigate('Cart')}
title="Cart"
color="blue"
/>
),
});
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Details Screen</Text>
<Button
onPress={() => this.props.navigation.navigate('Home')}
title="Go to home"
color="red"
/>
</View>
);
}
}
class CartScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Cart Screen</Text>
</View>
);
}
}
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
Details: DetailsScreen,
Cart: CartScreen
},
{
initialRouteName: "Home"
}
);
export default createAppContainer(AppNavigator);
How do you open a full screen modal from a windowed component in react navigation?
The opened modal has always the same size as the windowed component, from which the modal was navigated to.
I created a snack expo to show the problem here: https://snack.expo.io/Bk0N69FwX
This is just a basic example to show the problem, in my actual project the components are nested many times, so I cannot easily set the modal in the top level StackNavigator and navigate to it from a deeply nested component.
import * as React from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import { Constants } from 'expo';
import { createStackNavigator } from 'react-navigation';
// modal that should be rendered full screen
class Modal extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.text}>
This should be a full screen modal
</Text>
</View>
)
}
}
// windowed component, from which the modal will be navigated to
class NestedComponent extends React.Component {
render() {
return (
<View style={styles.nestedContainer}>
<Text style={styles.text}>
nested component
</Text>
<Button
onPress={() => this.props.navigation.navigate('modal')}
title="open modal"
/>
</View>
)
}
}
const ModalStackComponent = () => {
return (
<ModalStackNavigator />
)
}
const ModalStackNavigator = createStackNavigator(
{
nestedComponent: {
screen: NestedComponent,
navigationOptions: {
header: null,
},
},
modal: {
screen: Modal,
},
},
{
mode: 'modal',
}
)
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
// some stub container to limit screen size for nested component
<View style={styles.upperComponentContainer}>
<Text style={styles.text}>
upper component
</Text>
</View>
<ModalStackComponent />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'stretch',
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
},
upperComponentContainer: {
flex: 1,
backgroundColor: 'lightgrey',
justifyContent: 'center',
},
nestedContainer: {
flex: 1,
justifyContent: 'center',
},
text: {
textAlign: 'center',
fontSize: 20,
color: 'black',
},
});
For your requirement, you can use React native Modals.
https://facebook.github.io/react-native/docs/0.56/modal