How to call a class from another class in React-Native - reactjs

Oo .. sorry if my script is confusing because there are actually two options that I have deleted to make it look simpler but it makes the question direction unclear.
And this is the complete script
import { Button, Text, View, TouchableOpacity, StatusBar} from 'react-native';
import ScanQR from './ScanQR';
import SalesTrans from './SalesTrans';
import Inventory from './Inventory';
export default class Home extends Component{
constructor(props){
super(props)
}
render() {
return (
<View style={styles.container}>
<StatusBar barStyle = "dark-content" hidden = {false} backgroundColor = "yellow" translucent = {true}/>
<TouchableOpacity
onPress={this.props.navigation.navigate('ScanQR')}>
<Text style={styles.heading}>Scanning QR</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={this.props.navigation.navigate('SalesTrans')}>
<Text style={styles.heading}>Sales Transaction</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={this.props.navigation.navigate('Inventory')}>
<Text style={styles.heading}>Inventory Status</Text>
</TouchableOpacity>
</View>
);
}
}
And this is an android screen display
What I want is if Scanning QR is selected then the ScanQR page opens, likewise if the Invetory Status is selected, the Inventory page will open.
Thank you

If you want to render the ScanQR class in this class , you can do like
import { Text, View, TouchableOpacity, StatusBar} from 'react-native';
import ScanQR from './ScanQR';
export default class Home extends Component{
constructor(props){
super(props)
}
render() {
return (
<View style={styles.container}>
<StatusBar barStyle = "dark-content" hidden = {false} backgroundColor = "yellow" translucent = {true}/>
<ScanQR />
</View>
);
}
}
else if you want to navigate to ScanQR class from this class, then first add the ScanQR class inside the app navigation stack , and if its screen name is ScanQR , you can achieve something like, you did before,
import { Text, View, TouchableOpacity, StatusBar} from 'react-native';
export default class Home extends Component{
constructor(props){
super(props)
}
render() {
return (
<View style={styles.container}>
<StatusBar barStyle = "dark-content" hidden = {false} backgroundColor = "yellow" translucent = {true}/>
<TouchableOpacity onPress={this.props.navigation.navigate('ScanQR')}><Text style={styles.heading}>Scanning QR</Text></TouchableOpacity>
</View>
);
}
}
feel free to ask any doubts

if you want to access child class then you need to use props and if you want to access parent class from child then refs.
you can find full answer here

Related

Hide header from old page in react-native

I'm currently developing on a react-native application and I'm stucked at something for some time.
The problem is that I have a setup like this
Home Page -> Settings Page -> Information Page
I've hidden the header on home page, made a visible header on Settings Page and what I want to do:
I want to hide the header from the settings page when I navigate to Information Page. I mean I want that the third page gets all the space from the screen.
I'll attach a snack example of what happens in my case...
Hope someone could tell me a solution.
Thank you in advance! :)
https://snack.expo.io/#sapuu_ae/example-snack-stack -> open it on android/iOS device, it won't show good on web simulator.
The problem isn't the header, it's just that your navigation setup is a bit funky. Here are two working versions which use a different navigation setup. First, we need to define our screens.
class Home extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph} onPress={() => this.props.navigation.navigate('Second')}>
Press it
</Text>
</View>
);
}
}
class Second extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>
Second Page
</Text>
<Text style={styles.paragraph} onPress={() => this.props.navigation.navigate('Third')}>
Press for Third Page
</Text>
</View>
);
}
}
class Third extends React.Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.paragraph}>
Third page here
</Text>
</View>
);
}
}
This one assumes that all screens are part of the same stack:
const RootStack = createStackNavigator({
Home: Home,
Second: Second,
Third : Third
});
const AppContainer = createAppContainer(RootStack);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}
This one assumes that the third screen is contained in another stack, along with the second screen.
const secondScreenStack = createStackNavigator({
Second: Second,
Third: Third
}, {
defaultNavigationOptions: {
header: null
}
});
const RootStack = createStackNavigator({
Home: Home,
Second: secondScreenStack
});
const AppContainer = createAppContainer(RootStack);
export default class App extends React.Component {
render() {
return <AppContainer />;
}
}

Wrong result in react-native when I use flexDirection

I use the below code:
import React from 'react';
import { Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={{paddingTop:30,flexDirection:'row',}}>
<View style={{backgroundColor:'red',width:50,height:50}}><Text>1</Text></View>
<View style={{backgroundColor:'green',width:50,height:50}}><Text>2</Text></View>
</View>
);
}
}
and the result is:
I think the correct result should be:
why is the result not what I expect it to be?
use flex instead of height and width like this:
import React from 'react';
import { Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={{paddingTop:30,flexDirection:'row',}}>
<View style={{backgroundColor:'red',flex:.5}}><Text>1</Text></View>
<View style={{backgroundColor:'green',flex:.5}><Text>2</Text></View>
</View>
);
}
}
you can set flex according to yourself. this is just an example...
I find the problem, it's because of location that set in Genymotion, I use below code in App.js and solve the problem
import {I18nManager} from 'react-native'
I18nManager.forceRTL(false)

Update parent React component from child component

I'm using react context api to show my data everywhere and updating from everywhere I want that my data can be show on multiple screens and I can update from more than one class I need to use that globally.
When I try to update it from class profile screens nothing happen but it can be updating from class home screen.
How Can I show my data in consumer without using like this ,and show this data globally
const Context = React.createContext("default value")
global.cart = 1;
Class home screen that is context provider class
class HomeScreen extends Component<Props> {
constructor(props){
super(props);
this.state={
contextData:5}}
render() {
return (
<View>
<Context.Provider value={this.state.contextData}>
<Button title="Increment" onPress={++global.cart;
this.setState({contextData:global.cart})}/>
</Context.Provider>
<ProfileScreens/>
</View>
)
}
}
text that I need to use and show in many screens
class ProfileScreen extends Component<Props> {
render() {
return (
<View style={{}}>
<Context.Consumer>
{data=> <Text style={{fontSize:50}}>{data.toString()}</Text>}
</Context.Consumer>
</View>
);
}
}
another class which is changing the context provider data
class ProfileScreens extends Component<Props> {
constructor(props){
super(props);
this.state={contextData:5}}
render() {
return (
<View >
<Context.Provider value={this.state.contextData}>
<ProfileScreen/>
<Button title="decrementss" onPress={()=>{ ++global.cart;
this.setState({contextData:global.cart})}}/>
</Context.Provider>
</View>
);
}
}
you need to pass a callback down from HomeScreen to ProfileScreens
this callback would be called within ProfileScreens and trigger HomeScreen state change:
in HomeScreen:
...
<ProfileScreens changeHomeScreen={() => this.setState({...})}/>
...
then in ProfileScreens:
...
<Button title="decrementss" onPress={()=>{ this.props.changeHomeScreen() }}/>
...

Reloading an animation React-native-animatable library

guy's I'm using the react-native-animatable library. Basically, when I load my app the animation runs, however, when I go to another tab and return to the initial page the animation doesn't run anymore. I think it's because it' doesn't get reloaded anymore and I was wondering how to reload a component. As you can see the View has an animation prop which is the animation which has to be loaded.
import React, { Component } from 'react';
import { Text, Button, StyleSheet, Image, ImageBackground, TouchableOpacity } from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import LinearGradient from 'react-native-linear-gradient';
import {Fonts} from '../components/Fonts';
import { createAnimatableComponent, View, } from 'react-native-animatable';
class Home extends React.Component {
render() {
return (
<View style={styles.container}>
<View animation='bounceInLeft'
style={styles.container1}>
<View style={styles.card1}>
<ImageBackground
source={require('../images/pictures/runop.jpg')}
style={{width:'100%', height:200, }}>
<Text
style={{fontSize:30, alignSelf:'center', color:'white',
fontFamily:Fonts.Nunito}}
> Sport Schema's</Text>
</ImageBackground>
</View>
</View>
<View animation='bounceInRight' style={styles.container2}>
<View style={styles.card2}>
<Image
source={require('../images/pictures/foodop.jpg')}
style={{width:'100%', height:200}}/>
</View>
</View>
<View animation='bounceInLeft' style={styles.container3}>
<View style={styles.card3}>
<Image
source={require('../images/pictures/blogop.jpg')}
style={{width:'100%', height:200}}/>
</View>
</View>
</View>
);
}
}
Thanks for your help. I eventually got it to work with a different method.
I used the withNavigationFocus from react-navigation to get the isFocused props of the current screen. Then i just used an if statement if screen is focused then run animation else dont.
import {withNavigationFocus} from 'react-navigation';
class Profile extends React.Component {
constructor(props) {
super(props);
}
render()
// This checks if current screen is focused then run the animation otherwise dont.
{
if (this.props.isFocused && this.animation) {
this.animation.bounce(800)
}
return (
<View ref={(ref) => {this.animation = ref;}}
style={styles.container3}>
<View style={styles.card3}>
<Text> hii</Text>
</View>
</View>
);
}
}
});
export default withNavigationFocus(Profile); // <- dont forget this!!
If you are using react-navigation, below solution might work for you.
Create a function which would start the animation after some milliseconds and pass it to the next screen as params. Example,
SCREEN A
animateFunction() {
setTimeout(() => {
// start your animation
}, 100);
}
navigation.navigate(SCREEN_NAME, { startPrevScreenAnimation: animateFunction });
And in the next screen call that function when the component unmounts (componentWillUnmount()). Example,
SCREEN B
componentWillUnmount() {
this.props.navigation.state.params.startPrevScreenAnimation();
}
I said some milliseconds because you would want the animation to start once the screen transition is complete.
OR
Add a listener to your screen which fires an event when the screen is in focus.
if (this.props.navigation) {
this.willFocusSubscription = this.props.navigation.addListener(
'willFocus',
() => { // Run your animation },
);
}

Undefined is not a function: Timers - React Native

I am trying to make an app where the SplashScreen is shown for 600 milliseconds and then the Mainscreen is displayed. I used the setTimeOut method in componentDidmount, but I am getting the error as shown here. The necessary code is also provided below.
import React, { Component } from 'react';
import {Image,Dimensions, Button, Text, StyleSheet, View, TouchableOpacity} from 'react-native';
var timePassed;
class SplashScreen extends Component{
constructor(props){
super(props);
this.state={
timePassed: false
}
}
componentDidMount() {
this.setTimeout( () => {
this.setState({timePassed: true})
},600);
}
render(){
if(!this.state.timePassed){
return(
<View style={styles.container}>
<Image style={styles.logo} source={require('./Images/logo.jpg')} resizeMode="contain" />
<Text style={styles.deadlineFont}>Deadline</Text>
</View>
);
}
else{
return (
<View>
<MainScreen />
</View>
);
}
}
}
Problem: setTimeout is wrongly called with this but is not a method defined on your class.
Solution: Change this.setTimeout( () => { to setTimeout( () => {.
Here's a working example of your code: https://repl.it/Iqfk/1

Resources