I am trying to navigate between the screens. I installed npm react-navigation for this purpose. I am trying to go back from my AutoCompActivity page to app.js page. I have the following code on my AutoCompActivity page:
import HomeActivity from '../App'
class AutocompActivity extends Component {
constructor(props) {
super(props);
this.state = {
// Default Value of this State.
Loading_Activity_Indicator: true,
text:'',
selected_topic_id: -1,
}
this.arrayholder=[];
}
OpenHomePageFunction = () =>
{
this.props.navigation.navigate('Home');
}
and finally, I have this in my code:
export default MyNewProject= StackNavigator(
{
Home: {screen:HomeActivity}
}
I am getting the below error:
My AutoCompActivity.js resides inside a folder called Module, module reside inside the root folder' and app.js resides into the root folder of application.
Below is my App.js code:
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View, Button, Image, TouchableOpacity,Platform } from 'react-native';
import { StackNavigator } from 'react-navigation';
import MissionActivity from './Modules/MissionActivity' ;
import AutoCompActivity from './Modules/AutoCompActivity' ;
import SearchServices from './Modules/SearchServices';
class MainActivity extends Component {
constructor(){
super();
this.state={
isVisible : true,
}
}
Hide_Splash_Screen=()=>{
this.setState({
isVisible : false
});
}
componentDidMount(){
var that = this;
setTimeout(function(){
that.Hide_Splash_Screen();
}, 5000);
}
static navigationOptions = {
title: '',
};
OpenSecondActivityFunction = () =>
{
this.props.navigation.navigate('Mission');
}
OpenThirdActivityFunction = () =>
{
this.props.navigation.navigate('autoComp');
}
OpenSearchSer = () =>
{
this.props.navigation.navigate('SearchSer');
}
render()
{
let Splash_Screen = (
<View style={styles.SplashScreen_RootView}>
<View style={styles.SplashScreen_ChildView}>
{/* Put all your components Image and Text here inside Child view which you want to show in Splash Screen. */}
<Image source={require('./Resources/CAC.png')}
style={{width:'100%', height: '100%', resizeMode: 'contain'}} />
</View>
<TouchableOpacity
activeOpacity = { 0.5 }
style={styles.TouchableOpacity_Style}
onPress={this.Hide_Splash_Screen} >
<Image source={{uri: 'https://reactnativecode.com/wp-content/uploads/2018/01/close_button.png'}}
style={{width:25, height: 25}} />
</TouchableOpacity>
</View> )
return(
<View style = { styles.MainContainer }>
<View style={styles.toolbar}>
<Image
resizeMode='contain'
style={styles.toolbarTitle}
source={require('./Resources/LogoWithDesc.jpg')} />
</View>
<View>
<Image
style={styles.title}
source={require('./Resources/Pot.png')} />
</View>
<View style={styles.searchButton}>
<Button onPress = { this.OpenSecondActivityFunction } title = 'Mission'/>
</View>
<View style={styles.searchButton}>
<Button onPress = { this.OpenThirdActivityFunction } title = 'Available Services'/>
</View>
{
(this.state.isVisible === true) ? Splash_Screen : null
}
</View>
);
}
}
export default ActivityProject = StackNavigator(
{
First: { screen: MainActivity, navigationOptions:{header:null} },
Mission: { screen: MissionActivity },
SearchSer: { screen: SearchServices },
autoComp:{screen: }
});
Related
I am using react-navigation for routing between screens. Now, the scenario is I have used SwitchNavigator for authentication.
Example:
SplashScreen
this.props.navigation.navigate(userToken? 'App' : 'Auth', { extraParams: value});
LoginScreen / Home Screen
this.props.navigation.state.params.extraParams
This returns only routeName and key. Please find the reference code that I am using.
import React from 'react';
import {
ActivityIndicator,
AsyncStorage,
Button,
StatusBar,
StyleSheet,
View,
} from 'react-native';
import { createStackNavigator, createSwitchNavigator, createAppContainer } from 'react-navigation';
class SignInScreen extends React.Component {
static navigationOptions = {
title: 'Please sign in',
};
render() {
return (
<View style={styles.container}>
<Button title="Sign in!" onPress={this._signInAsync} />
</View>
);
}
_signInAsync = async () => {
await AsyncStorage.setItem('userToken', 'abc');
this.props.navigation.navigate('App');
};
}
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome to the app!',
};
render() {
return (
<View style={styles.container}>
<Button title="Show me more of the app" onPress={this._showMoreApp} />
<Button title="Actually, sign me out :)" onPress={this._signOutAsync} />
</View>
);
}
_showMoreApp = () => {
this.props.navigation.navigate('Other');
};
_signOutAsync = async () => {
await AsyncStorage.clear();
this.props.navigation.navigate('Auth');
};
}
class OtherScreen extends React.Component {
static navigationOptions = {
title: 'Lots of features here',
};
render() {
return (
<View style={styles.container}>
<Button title="I'm done, sign me out" onPress={this._signOutAsync} />
<StatusBar barStyle="default" />
</View>
);
}
_signOutAsync = async () => {
await AsyncStorage.clear();
this.props.navigation.navigate('Auth');
};
}
class AuthLoadingScreen extends React.Component {
constructor() {
super();
this._bootstrapAsync();
}
// Fetch the token from storage then navigate to our appropriate place
_bootstrapAsync = async () => {
const userToken = await AsyncStorage.getItem('userToken');
// This will switch to the App screen or Auth screen and this loading
// screen will be unmounted and thrown away.
this.props.navigation.navigate(userToken ? 'App' : 'Auth');
};
// Render any loading content that you like here
render() {
return (
<View style={styles.container}>
<ActivityIndicator />
<StatusBar barStyle="default" />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
});
const AppStack = createStackNavigator({ Home: HomeScreen, Other: OtherScreen });
const AuthStack = createStackNavigator({ SignIn: SignInScreen });
export default createAppContainer(createSwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: AppStack,
Auth: AuthStack,
},
{
initialRouteName: 'AuthLoading',
}
));
Can anyone please help to get an appropriate solution to pass extra params from SplashScreen to HomeScreen or LoginScreen?
i have my app like this : https://i.gyazo.com/4cfe178d3a59bf4e7449a7aacd0f114e.png
It is a app for play to a drinking game :p. I want to save all of input already the four input and before and after the fields that the user has added
import React, { Component } from 'react';
import {
View,
Text,
Button,
ScrollView,
TextInput,
TouchableOpacity,
StatusBar
} from 'react-native';
import { createStackNavigator } from 'react-navigation';
import { style } from './style';
class Form extends Component {
constructor(props) {
super(props);
StatusBar.setBarStyle('light-content', true);
console.log(this.props);
state = {
users: [{
id:1,
prenom:''
}, {
id:2,
prenom:''
}, {
id:3,
prenom:''
}, {
id:4,
prenom:''
}]
}
}
saveUser = value => {
console.log('test');
};
showInput() {
return state.users.map((item) => {
console.log(item);
return (
<TextInput
key={item.id}
style={style.input}
placeholder={`Prénom ${item.id}`}
placeholderTextColor="#29235c"
/>
);
});
}
render() {
return this.props.fontLoaded ? (
<View style={style.bgWhite}>
<ScrollView>
{
this.showInput()
}
<View style={style.morePlayer}>
<Text style={style.morePlayerText}>+</Text>
</View>
</ScrollView>
<View style={style.center}>
<TouchableOpacity
activeOpacity={0.9}
onPress={() => this.props.navigation.navigate('Game')}
style={style.btnPlay}
>
<Text style={style.textPlay}>ON TEASE!</Text>
</TouchableOpacity>
<Button title="Go to Details" onPress={() => this.props.navigation.navigate('Game')} />
</View>
</View>
) : null;
}
}
export default Form;
Should I save this in the asyncstorage ? I want to pass the all value of input in the params to go in other screen.
Thanks,
If you just need to pass the params to another screen you can just pass an object as the second argument of navigate.
this.props.navigation.navigate('Game', {
users: this.state.users,
otherParam: 'anything you want here',
});
Hello I am trying to make a Instagram like button with react-native by changing the image on press, but when I press the image no changes
Everything is up to date. And the code has no errors.
Here is my code:
import React, { Component } from 'react';
import { View, Text, StyleSheet, Image,navigation,TouchableOpacity } from 'react-native';
import { Container, Content, Badge, Left, Icon, Header} from 'native-base';
import { DrawerActions } from 'react-navigation';
class HomePage extends Component {
constructor(props){
super(props)
this.state = {
likedQ: false,
uri: require('./images/mianIcons/like.png')
}
}
_ifLiked = () => {
likedQ = true;
uri: require('./images/mianIcons/like3.png')
}
render(){
return(
<View>
<Header>
<Left>
<Icon name="ios-menu" onPress={()=> this.props.navigation.openDrawer()}
/>
</Left>
</Header>
<TouchableOpacity onPress={this._ifLiked()}>
<Image
style={{width: 32 , height: 32 ,}}
source={require(uri)}
/>
</TouchableOpacity>
</View>
)
}
}
export default HomePage;
You should set state to rerender the component
_ifLiked = () => {
this.setState({
likedQ: true,
uri: require('./images/mianIcons/like3.png')
})
}
change your onPress function like this. It is basic thing that you should set state for react components to update
There are some more corrections. Following is the corrected code
class HomePage extends Component{
constructor(props){
super(props)
this.state = {
likedQ: false,
uri: './images/mianIcons/like.png'
}
}
_ifLiked = () => {
this.setState({
likedQ: true,
uri: require('./images/mianIcons/like3.png')
}
}
render(){
return(
<View>
<Header>
<Left>
<Icon name="ios-menu" onPress={()=> this.props.navigation.openDrawer()} />
</Left>
</Header>
<TouchableOpacity onPress={() => this._ifLiked}>
<Image style={{width: 32 , height: 32}} source={require(this.state.uri)} />
</TouchableOpacity>
</View>
)}
}
I have created a side menu using drawer navigation. i am getting shadow overlay on the back view. I want to remove the shadow overlay.
Here is what I am getting right now. you see that I am getting a shadow overlay over my view when the drawer is open.
Here is what I want I want the view to be no shadow over the view.
please find below my code which creates a side menu using drawer navigation.
// Drawer.js
import React, { Component } from 'react';
import { View } from 'react-native';
import { DrawerNavigator } from 'react-navigation';
import Home from './AppNavigation';
import { SideMenu } from "./../Common/UIComponents";
import { widthScale } from "./../Common/Utils/Scaling";
export default DrawerStack = DrawerNavigator({
Home: { screen: Home },
MyAccount: { screen: () => <View /> },
MessageToBigFm: { screen: () => <View /> },
MeetTheMJs: { screen: () => <View /> },
Videos: { screen: () => <View /> },
AboutUs: { screen: () => <View /> },
ContactUs: { screen: () => <View /> },
TermsAndConditions: { screen: () => <View /> }
}, {
contentComponent: SideMenu,
drawerWidth: widthScale(320),
drawerBackgroundColor: "transparent",
style: { backgroundColor: "transparent", opacity: 0, shadowOpacity: 0, shadowColor: "transparent" }
});
Side menu js file
// SideMenu.js
import React, { Component } from "react";
import { View, Text, ScrollView, Platform } from "react-native";
import { NavigationActions } from "react-navigation";
import style from "./style";
import SideMenuHeader from "./SideMenuHeader";
import { ListFlat } from "./../../UIComponents";
import SideMenuData from "./SideMenuData";
import SideMenuCell from "./SideMenuCell";
import NavigationUtil from "./../../Utils/NavigationUtil";
class SideMenu extends Component {
constructor(props) {
super(props);
this.navigateToScreenWithIndex = this.navigateToScreenWithIndex.bind(this);
this.renderItemSeperator = this.renderItemSeperator.bind(this)
}
navigateToScreenWithIndex(index) {
const routeData = SideMenuData[index];
if (!routeData) {
return null;
}
const routeKey = routeData.navigationKey;
if (routeKey === null) {
return;
}
const navigateAction = NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: routeKey })
]
});
this.props.navigation.dispatch(navigateAction);
}
renderItemSeperator({ leadingItem }) {
if (leadingItem.key === 4) {
return <View style={style.seperator} />
} else {
return null;
}
}
render() {
return (
<View style={style.container}>
{Platform.OS === "ios" && <View style={style.statusBar} />}
<View style={style.listContainer}>
<ListFlat
horizontal={false}
renderHeader={() => <SideMenuHeader />}
data={SideMenuData}
CellComponent={SideMenuCell}
otherProps={{ onCellPress: this.navigateToScreenWithIndex }}
renderSeparator={this.renderItemSeperator}
/>
</View>
</View>
);
}
}
export default SideMenu;
I had a similar situation where React's Material UI adds a "MuiBackdrop-root" class div upon showing the Drawer. This was on web, but a mobile version of styled-components exists for React-Native--it could work.
Using the styled-components library, I used a CSS property similar to the following to hide it using "display: none". You have to use the > to directly target the element.
Something like this:
const MyDrawer = styled(Drawer)`
& > .MuiBackdrop-root {
display: none;
}
`;
Hope this helps you!
My React Js skills are very basic,What I want to get is when I click on a category, I show a list of posts of the category selected in a new screen in this case is PostsScreen.
The problem is that i get the itemId null.
I don't know what i'm doing wrong.
These are my screens and the routes component
Categories Screen
import React, {Component} from 'react';
import { NavigationActions, DrawerNavigator, StackNavigator } from 'react-navigation';
import{Dimensions, Button, View, SafeAreaView, FlatList, ActivityIndicator, TouchableOpacity } from 'react-native';
export default class WGoals extends Component {
static navigationOptions = {
title: 'Categories'
};
navigateToScreen = (route, params) => () => {
const navigateAction = NavigationActions.navigate({
routeName: route,
params: params
});
this.props.navigation.dispatch(navigateAction);
}
constructor(props)
{
super(props);
this.state = {
isLoading: true,
}
}
render() {
return (
<Container style={styles.background_general}>
<TouchableOpacity onPress={this.navigateToScreen('PostsScreen', itemId = '1')} >
<Text>Category 1</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.navigateToScreen('PostsScreen', itemId = '2')} >
<Text>Category 2</Text>
</TouchableOpacity>
</Container>
);
}
}
Posts Screen
import React, {Component} from 'react';
import { NavigationActions, DrawerNavigator, StackNavigator } from 'react-navigation';
import{Dimensions, View, SafeAreaView, FlatList, ActivityIndicator } from 'react-native';
export default class Posts extends Component {
static navigationOptions = {
title: 'Posts'
};
render() {
const { params } = this.props.navigation.state;
const itemId = params ? params.itemId : null;
return (
<Container style={styles.background_general}>
<Text>Details Screen</Text>
<Text>itemId: {JSON.stringify(itemId)}</Text>
</Container>
);
}
}
Routes
import React from 'react';
import CategoriesScreen from '../screens/Categories';
import PostsScreen from '../screens/Posts';
import SideMenu from './SideMenu';
import {DrawerNavigator, StackNavigator} from 'react-navigation'
const navigationOptions = {
navigationOptions: {
headerStyle: {
backgroundColor: '#f39c12',
},
headerTitleStyle: {
textAlign: 'center',
alignSelf: 'center',
fontSize: 20,
color: '#fff',
fontWeight: 'bold'
}
}
};
const leftIcon = (navigation, icon) => <Icon
name={icon}
style={{marginLeft: 20}}
size={20}
color="white"
onPress={() => navigation.navigate('DrawerOpen')}
/>;
const rightIcon = (navigation, icon) => <Icon
name={icon}
style={{marginLeft: 20}}
size={30}
color="white"
onPress={() => navigation.navigate('CategoriesScreen')}
/>;
const CategoriesScreenStack = StackNavigator (
{
Categories: {
screen: CategoriesScreen,
navigationOptions: ({navigation}) => ({
drawerIcon: ({tintColor}) => (<Icon name="home" size={24} style={{color: '#f39c12'}} />),
headerLeft: leftIcon(navigation, 'menu')
})
}
},
navigationOptions
);
const PostsScreenStack = StackNavigator(
{
PostsScreen: {
screen: PostsScreen,
navigationOptions: ({ navigation }) => ({
drawerIcon: ({ tintColor }) => (<Icon name="user" size={24} style={{ color: tintColor }} />),
headerLeft: leftIcon(navigation, 'menu')
})
}
},
navigationOptions
);
export default DrawerNavigator({
CategoriesScreen: {
screen: CategoriesScreenStack
},
PostsScreen: {
screen: PostsScreenStack
},
}, {
contentComponent: SideMenu,
drawerWidth: width * .7,
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoute: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle',
});
You want to pass itemId in an object to navigateToScreen, since you are accessing params as an object (params.itemId) in WorkoutsGoalsList, currently it is undefined.
Also, onPress expects a function reference. As it is now, you are actually calling the function so this.navigateGateToScreen will be called on every render. Check out the bind documentation, bind allows you to create a new function with a specific list of arguments:
render () {
return (
<Container style={styles.background_general}>
<TouchableOpacity
onPress={this.onPress.bind(this, '1')}
>
<Text>Category 1</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={this.onPress.bind(this, '2')}
>
<Text>Category 2</Text>
</TouchableOpacity>
</Container>
);
};
onPress = (id) => {
this.navigateToScreen('PostsScreen', { itemId: id })
};
You also do not need to curry your navigateToScreen function:
navigateToScreen = (route, params) => { // remove curry here
const navigateAction = NavigationActions.navigate({
routeName: route,
params: params,
});
this.props.navigation.dispatch(navigateAction);
};
Your props will look something like this:
this.props = {
navigation: {
state: {
params: {
itemId: '1',
}
}
}
};
It's less than optimal to bind in render because a new function will be created on every render call. A better way to structure the code is to create a dedicated component and pass an itemId and onPress function:
WGoals
export default class WGoals extends Component {
static navigationOptions = {
title: 'Categories',
};
navigateToScreen = (route, params) => {
const navigateAction = NavigationActions.navigate({
routeName: route,
params: params,
});
this.props.navigation.dispatch(navigateAction);
};
constructor(props) {
super(props);
this.state = {
isLoading: true,
};
}
render() {
return (
<Container style={styles.background_general}>
<Category name='Category1' onPress={this.navigateToScreen} itemId='1' />
<Category name='Category2' onPress={this.navigateToScreen} itemId='2' />
</Container>
);
}
}
Category
export default class Category extends Component {
render () {
const { name } = this.props;
return (
<TouchableOpacity
onPress={this.handlePress}
>
<Text>{name}</Text>
</TouchableOpacity>
);
}
handlePress = () => {
const { itemId, onPress } = this.props;
onPress('PostsScreen', { itemId: itemId });
}
}
In PostsScreens, you need to render itemId in a string or you can render the value of the variable by wrapping it in curly brackets ({itemId}). Below, I'm rendering it as a string and inserting the value of itemId into the string. Check out the template literal docs for more info on the syntax:
export default class Posts extends Component {
static navigationOptions = {
title: 'Posts',
};
render() {
const { params } = this.props.navigation.state;
const itemId = params ? params.itemId : null;
return (
<Container style={styles.background_general}>
<Text>'Details Screen'</Text>
<Text>`itemId: ${itemId}`</Text>
</Container>
);
}
}