StackNavigation props not working as expected - react-native

I've configured the navigation as best I can, however there are no errors when the app runs. The buttons change shade to show they've been pressed but sadly they don't navigate.
I've tried different versions of Expo, React and StackNavigation too.
Here's a copy of the MainNavigator:
import ArtGallery from "./ArtGallery";
import HighNet from "./HighNet";
import Economist from "./Economist";
import Main from "./Main";
import { createStackNavigator, createAppContainer } from "react-navigation";
const screens = {
ArtGallery: {
screen: ArtGallery
},
HighNet: {
screen: HighNet
},
Economist: {
screen: Economist
},
Main: {
screen: Main
}
}
const config = {
headerMode: 'none',
initialRouteName: 'Economist'
}
const MainNavigator = createStackNavigator(screens, config);
export default createAppContainer(MainNavigator);
And here's a copy of the Main.js:
import React, { Component } from "react";
import { Center } from "#builderx/utils";
import Button2 from "../symbols/button2";
import Button21 from "../symbols/button21";
import Button22 from "../symbols/button22";
import { View, StyleSheet, Text } from "react-native";
import { MainNavigation } from "../screens/MainNavigator";
export default class Main extends Component {
render() {
return (
<View style={styles.root}>
<Center horizontal>
<Text style={styles.title}>TV Network</Text>
</Center>
<Center horizontal>
<Button2
onPress={() => this.props.navigation.navigate("Winkball")}
style={styles.winkTv}
buttonContent="WinkBall TV" />
</Center>
<Center horizontal>
<Button21
onPress={() => this.props.navigation.navigate("HighNet")}
style={styles.highNet}
buttonContent="High Net Worth Channel"
/>
</Center>
<Center horizontal>
<Button22
onPress={() => this.props.navigation.navigate("Economist")}
style={styles.artGalleryTv}
buttonContent="Economist TV"
/>
</Center>
</View>
);
}
}
const styles = StyleSheet.create({
root: {
backgroundColor: "white",
flex: 1
},
title: {
height: "6.19%",
width: "64.53%",
top: 68,
position: "absolute",
backgroundColor: "transparent",
fontSize: 48,
color: "rgba(109,104,104,1)"
},
winkTv: {
top: 309,
position: "absolute",
height: "5.665024630541872%",
width: "33.06666666666666%"
},
highNet: {
top: 384,
position: "absolute",
height: "5.665024630541872%",
width: "57.333333333333336%"
},
artGalleryTv: {
top: 460,
position: "absolute",
width: "42.13%",
height: "4.06%"
}
});

Related

How to check for current active page in component?

I would like to apply different styling to a component, for example i have a back icon here
import React from 'react';
import { StyleSheet } from 'react-native';
import { Icon } from '#ui-kitten/components';
export const BackIcon = () => (
<Icon
style={styles.icon}
fill='#FFFFFF'
name='arrow-back-outline'
/>
);
const styles = StyleSheet.create({
icon: {
width: 35,
height: 35,
bottom: 115,
right: 145
},
});
Currently I only have 1 style applied to it, but I would like to know you can detect the current active page so that when the user is in page A the icon will be styled differently as to when the component is called in page B for instance.
You can pass it as a prop from the parent component
<Parent>
<BackIcon current/>
<BackIcon />
<BackIcon />
</Parent>
import React from 'react';
import { StyleSheet } from 'react-native';
import { Icon } from '#ui-kitten/components';
export const BackIcon = (props) => (
<Icon
style={props.current ? styles.activeIcon : styles.icon}
fill='#FFFFFF'
name='arrow-back-outline'
/>
);
const styles = StyleSheet.create({
icon: {
width: 35,
height: 35,
bottom: 115,
right: 145
},
activeIcon:
{
color:'orange',
width: 35,
height: 35,
bottom: 115,
right: 145
}
});

MultipleScreens(like a stack) on top of one another in react native

In react native, can we achieve a UI where there are multiple screens stacked on top of each other with each screen stacking on top of the other on click of a button.
Let's say, there is Screen A. Upon click of a button, Screen B is placed as a stack on Screen A and screen A is still partly visible as Screen B doesn't occupy the entire screen layout. Similarly, Screen C adds up to the stack upon the click of a button in Screen B and screen B is still visible along with screen A in the background. All these come with a side animation from the left (similar to navigation drawer). With a common button, all the above screens can be popped out from the stack and the previous screen comes to the top with a side animation again, this time to the right.
I wanted to understand if the above is possible in react native? If yes, how I can achieve it? I wish I can show the design but I cannot do that atm.
With react-native-vertical-view-pager you can do it.
install with:
npm install --save react-native-vertical-view-pager
or with yarn (if you use yarn):
yarn add react-native-vertical-view-pager
and use as follow:
import React from 'react';
import { StyleSheet, Text, View, Dimensions } from 'react-native';
import VerticalViewPager from 'react-native-vertical-view-pager';
const { width, height } = Dimensions.get('window');
export default class App extends React.Component {
render() {
return (
<VerticalViewPager
showsVerticalScrollIndicator={false}>
<View style={[styles.page_container, {backgroundColor: 'pink'}]}>
<Text>Page1: Open up App.js to start working on your app!</Text>
</View>
<View style={[styles.page_container, {backgroundColor: 'olive'}]}>
<Text>Page2: Changes you make will automatically reload.</Text>
</View>
<View style={[styles.page_container, {backgroundColor: 'lightblue'}]}>
<Text>Page3: Shake your phone to open the developer menu.</Text>
</View>
</VerticalViewPager>
);
}
}
const styles = StyleSheet.create({
page_container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
width,
height
}
});
with your screens on the place of the views.
I could achieve this functionality using a very cool library named 'react-native-modalfy'.
import React, { PureComponent } from 'react'
import {
Easing,
Dimensions,
StatusBar,
StyleSheet,
Text,
View,
} from 'react-native'
import { ModalProvider, createModalStack } from 'react-native-modalfy'
import CardModal from './modals/CardModal'
import Button from './components/Button'
const { width } = Dimensions.get('screen')
const config = { ModalA: CardModal, ModalB: CardModal, ModalC: CardModal }
const defaultOptions = {
transitionOptions: animatedValue => ({
opacity: animatedValue.interpolate({
inputRange: [0, 1, 2],
outputRange: [0, 1, .9],
}),
transform: [
{
perspective: 2000
},
{
translateX: animatedValue.interpolate({
inputRange: [0, 1, 2],
outputRange: [-width / 2, 0, 25],
}),
},
{
scale: animatedValue.interpolate({
inputRange: [0, 1, 2],
outputRange: [1.2, 1, .9],
}),
},
],
}),
animateInConfig: {
easing: Easing.bezier(.42,-0.03,.27,.95),
duration: 450,
},
animateOutConfig: {
easing: Easing.bezier(.42,-0.03,.27,.95),
duration: 450,
},
}
const stack = createModalStack(config, defaultOptions)
class App extends PureComponent {
render() {
return (
<ModalProvider stack={stack}>
<View style={styles.container}>
<StatusBar animated hidden translucent />
<Text style={styles.title}>RNM</Text>
<Button label="Open ModalA" modalToOpen="ModalA" color="tomato" />
<Button label="Open ModalB" modalToOpen="ModalB" color="darkcyan" />
<Button label="Open ModalC" modalToOpen="ModalC" color="deeppink" />
</View>
</ModalProvider>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'indigo',
alignItems: 'center',
justifyContent: 'center'
},
title: {
color: 'white',
fontSize: 54,
fontWeight: 'bold',
marginBottom: 50,
},
})
export default App
import React, { PureComponent } from 'react'
import {
Button as ButtonModule,
Dimensions,
StyleSheet,
Text,
View,
} from 'react-native'
import Button from '../components/Button'
const { width: ww, height: wh } = Dimensions.get('screen')
class CardModal extends PureComponent {
componentDidMount() {
const { modal } = this.props
this.modalListenerID = modal.addListener('onAnimate', this._handleAnimation)
}
componentWillUnmount() {
this.modalListenerID?.remove()
}
_handleAnimation = animatedValue => {
const { currentModal } = this.props.modal
console.info(`${currentModal}:`, animatedValue)
}
render() {
const {
currentModal,
closeModal,
closeModals,
closeAllModals,
params: { color },
} = this.props.modal
return (
<View style={[styles.card]}>
<Text style={styles.title(color)}>{currentModal}</Text>
<Button label="Open ModalA" modalToOpen="ModalA" color="tomato" />
<Button label="Open ModalB" modalToOpen="ModalB" color="darkcyan" />
<Button label="Open ModalC" modalToOpen="ModalC" color="deeppink" />
<ButtonModule title="Close" onPress={closeModal} color="dodgerblue" />
<ButtonModule title={`Close all ${currentModal}`} onPress={() => closeModals(currentModal)} color="dodgerblue" />
<ButtonModule title="Close all modals" onPress={closeAllModals} color="red" />
</View>
)
}
}
const styles = StyleSheet.create({
title: color => ({
color,
fontSize: 48,
fontWeight: 'bold',
marginBottom: 50,
}),
card: {
marginRight : 90,
width: ww,
height: wh,
backgroundColor: 'cyan',
elevation: 0,
alignItems: 'center',
justifyContent: 'center',
borderRadius: 0,
},
})
export default CardModal
import React, { PureComponent } from 'react'
import { TouchableOpacity, StyleSheet, Text } from 'react-native'
import { withModal } from 'react-native-modalfy'
class Button extends PureComponent {
openModal = () => {
const { color, modalToOpen, modal } = this.props
modal.openModal(modalToOpen, { color })
}
render() {
const { color, label } = this.props
return (
<TouchableOpacity onPress={this.openModal} style={styles.button(color)}>
<Text style={styles.label}>{label}</Text>
</TouchableOpacity>
)
}
}
const styles = StyleSheet.create({
button: backgroundColor => ({
backgroundColor,
paddingHorizontal: 60,
paddingVertical: 21,
borderRadius: 21,
marginBottom: 30,
}),
label: {
fontSize: 16,
fontWeight: '800',
color: 'white',
textAlign: 'center',
},
})
export default withModal(Button)

Webview&redabilitywebview works fine in android not in ios react native

I am using a inapp browser using webview and readbilitywebview. it works fine in android but in ios the webview dosent display any content other than title of news and in readbilitywebview getting an error "invariant violation require native component rncwkwebview manager not found in the ui manager"
Using expo cli for development.
Webview:
import React, { Component } from 'react';
import { WebView,StyleSheet,View } from 'react-native';
import { Container, Text } from 'native-base';
import { Ionicons } from '#expo/vector-icons';
import { Header } from 'react-native-elements';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import { NavigationActions, StackActions } from 'react-navigation';
import SimpleWebView from './webModal';
class MyWeb extends Component {
render() {
const { navigation } = this.props;
const title = JSON.stringify(navigation.getParam('title'))
const url = (navigation.getParam('url'))
return (
<View style={styles.container}>
<Header
backgroundColor="white"
/*leftComponent={<Ionicons name="md-arrow-round-back"
size={25}
onPress={() => {
alert('You tapped the button!');
}}/>}*/
centerComponent={
<Text
numberOfLines={1}
style={{
fontSize: 14,
fontWeight: 'bold'
}}>
{title}
</Text>}
rightComponent={
<Ionicons name="ios-book"
size={25}
onPress={() => {
this.props.navigation.navigate('Webview', {
url: (url),
title: (title)
});
}} />
}
/>
<WebView
source={{
uri: (navigation.getParam('url'))
}}
style={{ marginTop: 20 }}
/>
</View>
);
}
}
const MainNavigator = createStackNavigator({
Home: {
screen: MyWeb,
navigationOptions: {
header: null,
},
},
Webview: {
screen: SimpleWebView,
navigationOptions: {
header: null,
},
},
},
{
initialRouteName: 'Home',
}
);
const styles = StyleSheet.create({
container: {
flex: 1,
}
});
const Webpage = createAppContainer(MainNavigator);
export default Webpage;
Redabilitywebview
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import ReadabilityWebView from "react-native-webview-readability";
import Constants from 'expo-constants';
const css =
`body {
color: #2a2a2a;
}
img, figure {
display: none;
}
h1 {
border-bottom-width: 1px;
border-color: #ccc;
padding-bottom: 3px;
border-bottom-style:solid;
font-size: 1.6em;
font-weight: bold;
letter-spacing: .05em;
}
p {
letter-spacing: .03em;
}`;
export default class SimpleWebView extends React.Component {
render() {
const { navigation } = this.props;
return (
<View style={styles.continer}>
<ReadabilityWebView
automaticallyAdjustContentInsets={true}
htmlCss={css}
url={(navigation.getParam('url'))}
title=
{navigation.getParam('title')}
/>
</View>
);
}
}
const styles = StyleSheet.create({
continer: {
flex: 1,
paddingTop: Constants.statusBarHeight
}
});
workes in android but not in ios. Iam using expo cli.

Error: undefined is not an object (evaluating 'this.props.navigation.navigate')

I have created a separate route file and when I am trying to navigate between screens with the help of these routes with react-navigation using stackNavigator I am getting this error I have already tried other solutions available on Stack overflow but none of the answers solve my problem here is my code.
This is my Route.js file
import { createAppContainer, createStackNavigator } from 'react-navigation';
import Login from './screens/Login';
import Register from './screens/Register';
import Start from './screens/Start';
const AppNavigator = createStackNavigator({
Home: {
screen: Start,
},
LoginScreen: {
screen: Login,
},
RegisterScreen: {
screen: Register,
},
}, {
initialRouteName: 'Home',
navigationOptions: {
header: null
}
});
export default createAppContainer(AppNavigator);
And this is my component where I am trying to navigate
import React,{ Component } from 'react';
import { StyleSheet, View, KeyboardAvoidingView,Text } from 'react-native';
import NewButtons from './NewButtons';
import Logo from './Logo';
export default class Start extends Component{
constructor () {
super();
}
loginPress = () => {
this.props.navigation.navigate('LoginScreen');
}
registerPress = () => {
this.props.navigation.navigate('RegisterScreen');
}
render(){
return(
<KeyboardAvoidingView behavior='padding' style={styles.wrapper}>
<View style={styles.logoContainer}>
<Logo/>
<Text style={styles.mainHead}>Welcome to Food Zone</Text>
<Text style={{margin: 10, textAlign:'center'}}>Check out our menus, order food and make reservations{"\n"}{"\n"}</Text>
<NewButtons text="Login"
onPress={this.loginPress}/>
<NewButtons text="Register"
onPress={this.registerPress}/>
</View>
</KeyboardAvoidingView>
);
}
}
const styles = StyleSheet.create({
logoContainer: {
alignItems: 'center',
},
mainHead: {
fontFamily: 'PatuaOne',
color: '#ff9900',
fontSize: 28,
marginTop: -50,
},
})
And this in my button component
import React,{ Component } from 'react';
import { StyleSheet, View,Dimensions } from 'react-native';
import { Button, Text } from 'native-base';
const {width:WIDTH} = Dimensions.get('window')
export default class NewButtons extends Component{
constructor(props){
super(props);
}
handlePress = () => {
this.props.onPress();
}
render(){
return(
<View style={styles.ButtonContainer}>
<Button light style={styles.mainButtons} onPress={this.handlePress()}>
<Text style={styles.textProps}>{this.props.text}</Text>
</Button>
</View>
);
}
}
const styles = StyleSheet.create({
textProps:{
fontFamily: 'PatuaOne',
color: '#ffffff',
},
mainButtons: {
backgroundColor: "#ff9900",
width: 250,
margin: 5,
color: '#ffffff',
justifyContent: 'center',
width: WIDTH -75,
borderRadius: 10,
},
ButtonContainer: {
alignItems: 'center',
}
})
I managed to remove this error by importing routes in App.js file and by calling it in index.js here is my code of App.js file.
import React, {Component} from "react";
import Routes from "./Routes";
const App = () => <Routes/>
export default App;

Cant find the variable React-native

native . I made the status component and router.js file .The emulator giving me error Cant find varible i do not know what is the problem but im getting this error in emulator .
here is my code
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
import StatusComponent from './component/StatusComponent';
import HeaderComponent from './component/headerComponent';
import Router from './component/Router';
import MainPage from './component/MainPage';
export default class Point extends Component {
render() {
return (
<View style={{flex: 1,backgroundColor: 'white'}}>
<StatusComponent/>
<HeaderComponent/>
</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,
},
} );
AppRegistry.registerComponent('Point', () => Point);
and here is my status component
import React,{ Component } from 'react';
import {
Text,
View,
StyleSheet
} from 'react-native';
export class StatusComponent extends Component{
render()
{
return(
<View style={styles.Bar}>
</View>
)
};
}
export default StatusComponent;
const styles=StyleSheet.create({
Bar:{
backgroundColor: 'white',
height: 20
}
})
here is code for Router.Js this file cousing the issue
import React, { Component } from 'react'
import {
StyleSheet,
Text,
Navigator,
TouchableOpacity
} from 'react-native'
import MainPage from './MainPage'
import Sports from './Sports'
export default class Router extends Component {
constructor(){
super()
}
render() {
return (
<Navigator
initialRoute = {{ name: 'MainPage', title: 'MainPage' }}
renderScene = { this.renderScene }
navigationBar = {
<Navigator.NavigationBar
style = { styles.navigationBar }
routeMapper = { NavigationBarRouteMapper } />
}
/>
);
}
renderScene(route, navigator) {
if(route.name == 'MainPage') {
return (
<MainPage
navigator = {navigator}
{...route.passProps}
/>
)
}
if(route.name == 'Sports') {
return (
<Sports
navigator = {navigator}
{...route.passProps}
/>
)
}
}
}
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, navState) {
if(index > 0) {
return (
<TouchableOpacity
onPress = {() => { if (index > 0) { navigator.pop() } }}>
<Text style={ styles.leftButton }>
Back
</Text>
</TouchableOpacity>
)
}
else { return null }
},
RightButton(route, navigator, index, navState) {
if (route.openMenu) return (
<TouchableOpacity
onPress = { () => route.openMenu() }>
<Text style = { styles.rightButton }>
{ route.rightText || 'Menu' }
</Text>
</TouchableOpacity>
)
},
Title(route, navigator, index, navState) {
return (
<Text style = { styles.title }>
{route.title}
</Text>
)
}
};
const styles = StyleSheet.create({
navigationBar: {
backgroundColor: 'blue',
},
leftButton: {
color: '#ffffff',
margin: 10,
fontSize: 17,
},
title: {
paddingVertical: 10,
color: '#ffffff',
justifyContent: 'center',
fontSize: 18
},
rightButton: {
color: 'white',
margin: 10,
fontSize: 16
}
})
In the StatusComponent file, you have export in front of the class StatusComponent extends Component. You should remove that export and leave the export default StatusComponent; at the bottom.
If after that, it still doesn't work then check the absolute path you are using to import the StatusComponent. Make sure it's correct
there is mistake in statusComponent file and thats very stupid mistake