Issue with photos length - javascript

I am facing 2 issues related to length of my selected photos:
When selecting photos, it lets me to select 5 photos without any issue (it fits my length restriction), however it doesn't save the chosen photos, when I go to the next screen. In another scenario, when I am at the same screen where I choose photos and I choose 6 photos, it selects the 6 photo but the warning popup will appear and say that its currently supports 5, then when I go to next screen its saves the selected photos unlike previously.
If I deselect photos and then try to select another photos (still in my length limit) popup jumps with selection limit and doesn't let me choose photos, when I go to the next screen it saves the changes from previous selection and not from current one.
import React from 'react';
import {
View,
ScrollView,
Image,
Dimensions,
TextInput,
Text,
StatusBar,
TouchableHighlight,
Linking,
Keyboard,
CameraRoll,
KeyboardAvoidingView
} from 'react-native';
import {connect} from 'react-redux';
import {ActionCreators} from '../redux/actions';
import {bindActionCreators} from 'redux';
import Colors from '../constants/Colors';
import api from '../api';
import {
getEmailAddress,
showError,
renderMessageBar,
registerMessageBar,
unregisterMessageBar
} from '../utils/ComponentUtils';
import {
regularHeader,
mainHeader
} from '../utils/Headers';
import {NavigationActions} from 'react-navigation';
import {SelectionLimitDialog} from '../utils/Dialogs';
import {ifIphoneX, isIphoneX} from 'react-native-iphone-x-helper';
import {SafeAreaView} from 'react-navigation';
// specific component imports.
import {List, ListItem} from 'react-native-elements'
import {Button} from 'react-native-elements'
import Loader from '../components/Loader';
import LoaderError from '../components/LoaderError';
import SelectedPhoto from '../components/SelectedPhoto';
class MultiSafeeScreen extends React.Component
{
static navigationOptions = ({navigation}) => {
const {params} = navigation.state;
const isIncome = params ? params.isIncome : false;
const notificationAction = params ? params.notificationAction : () => {};
const isShowBack = params ? params.isShowBack : false;
return mainHeader({
isShowBack: isShowBack,
backAction: () => navigation.goBack(),
notificationAction: () => notificationAction(),
income: isIncome
});
};
constructor(props) {
super(props);
this.selectedPhotos = [];
this.state = {
photos: null,
loader: {
loading: 0,
message: "Loading photos..."
},
selectedPhotos: [],
supportLength: 5
};
this.props.navigation.setParams({notificationAction: this.onNotification, isIncome: this.props.isNewNotifications});
}
UNSAFE_componentWillReceiveProps(newProps) {
if (newProps.isNewNotifications !== this.props.isNewNotifications) {
this.props.navigation.setParams({notificationAction: this.onNotification, isIncome: newProps.isNewNotifications});
}
}
componentDidMount() {
registerMessageBar(this.refs.alert);
let options = {
first: 30,
assetType: 'Photos',
}
CameraRoll.getPhotos(options)
.then(r => {
this.setState({
photos: r.edges,
loader: {
loading: 1,
message: "Loading photos..."
},
});
})
.catch((err) => {
//Error Loading Images
});
StatusBar.setHidden(false);
}
componentWillUnmount() {
unregisterMessageBar();
this.props.setSelectedPhotos(0);
}
onNotification = () => {
this.props.setNewNotifications(false);
this.props.navigation.navigate("Notifications");
}
closeKeyboard = () => {
Keyboard.dismiss();
}
onSelectPhoto = (photo, index) => {
let photos = new Set([...this.selectedPhotos]);
let len = photos.size + 1 ;
console.log('photos')
if (len > this.state.supportLength) {
this.limitDialog.open();
this.setState({selectedPhotos: this.selectedPhotos});
this.props.setSelectedPhotos(len);
}
else {
photos.add(photo);
this.selectedPhotos = Array.from(photos);
}
}
onDeselectPhoto = (photo, index) => {
let photos = new Set([...this.state.selectedPhotos]);
let len = photos.size - 1;
photos.delete(photo);
this.setState({selectedPhotos: Array.from(photos)});
this.props.setSelectedPhotos(len);
}
onNext = () => {
this.props.navigation.navigate("MultiSafeeCreate", {
isShowBack: true,
selected: [...this.state.selectedPhotos]
});
}
renderLoader() {
let {width, height} = Dimensions.get('window');
let photoWidth = width/3;
if (this.state.loader.loading === 0) {
return <Loader style={{justifyContent: 'center', alignItems: 'center'}} message={this.state.loader.message}/>
}
else if (this.state.loader.loading === 2) {
return <LoaderError style={{justifyContent: 'center', alignItems: 'center'}} message={this.state.loader.message}/>
}
// if photos are null do nothing, else if empty show onbording
// if has photos show photos.
if (this.state.photos === null) {
return <Loader style={{justifyContent: 'center', alignItems: 'center'}} message={this.state.loader.message}/>
}
else {
return (
<View style={{width: width, maxHeight: 600}}>
<ScrollView >
<View style={{flexDirection: 'row', width: width, flexWrap: 'wrap',marginBottom:40, justifyContent: 'space-between'}}>
{
this.state.photos.map((p, i) => {
return (
<SelectedPhoto
key={i}
index={i}
style={{
width: photoWidth,
height: photoWidth,
}}
borderColor = "white"
limit={this.state.supportLength}
photo={p}
onSelectPhoto={this.onSelectPhoto}
onDeselectPhoto={this.onDeselectPhoto}
/>
);
})
}
</View>
</ScrollView>
<View style={{ position:'absolute', right:-15, top:475 }}>
<Button
onPress={this.onNext}
containerViewStyle={{width: width}}
backgroundColor={Colors.red}
title='NEXT' />
</View>
</View>
);
}
}
render() {
return (
<View style={{flex: 1, backgroundColor: Colors.white}}>
{this.renderLoader()}
<SelectionLimitDialog ref={(el) => this.limitDialog = el} />
{renderMessageBar()}
</View>
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
function mapStatesToProps(state) {
return {
isNewNotifications: state.isNewNotifications
};
}
export default connect(mapStatesToProps, mapDispatchToProps)(MultiSafeeScreen);

Related

How to hide splash screen once images are loaded

I am using expo and want to show the splash screen until images are all loaded. I am loading images from a url.
What is supposed to happen is when onLoad is called, numberOfImagesLoaded increases by 1, and useAppIsReady is run again. Then there is a check
const imagesAreLoaded = numberOfImagesLoaded > 2;.
When numberOfImagesLoaded > 2, appIsReady is true, then onLayoutRootView gets called and the splash screen gets hidden.
However, I am not sure why when onLoad is called, numberOfImagesLoaded in useAppIsReady does not seem to increase.
App.js
import { StatusBar } from "expo-status-bar";
import { Image, StyleSheet, Text, View } from "react-native";
import { useFonts } from "expo-font";
import * as SplashScreen from "expo-splash-screen";
import React, { useCallback, useState } from "react";
import useAppIsReady from "./useAppIsReady";
import data from "./data";
SplashScreen.preventAutoHideAsync();
export default function App() {
const [numberOfImagesLoaded, setNumberOfImagesLoaded] = useState(0);
const appIsReady = useAppIsReady(numberOfImagesLoaded);
const onLayoutRootView = useCallback(async () => {
if (appIsReady) {
await SplashScreen.hideAsync();
}
}, [appIsReady]);
if (!appIsReady) {
return null;
}
return (
<View onLayout={onLayoutRootView} style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<Images setNumberOfImagesLoaded={setNumberOfImagesLoaded} />
<StatusBar style="auto" />
</View>
);
}
const Images = ({ setNumberOfImagesLoaded }) => {
return (
<>
{data.map(({ imgSrc }) => {
return (
<MyImage
key={imgSrc}
imgSrc={imgSrc}
setNumberOfImagesLoaded={setNumberOfImagesLoaded}
/>
);
})}
</>
);
};
const MyImage = ({ imgSrc, setNumberOfImagesLoaded }) => {
const onLoad = () => {
setNumberOfImagesLoaded((prev) => prev + 1);
};
return (
<Image source={{ uri: imgSrc }} style={styles.image} onLoad={onLoad} />
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
image: {
flex: 1,
width: "100%",
},
});
useAppIsReady.js
import { useFonts } from "expo-font";
import * as SplashScreen from "expo-splash-screen";
import React, { useState, useCallback } from "react";
const useAppIsReady = (numberOfImagesLoaded) => {
const [appIsReady, setAppIsReady] = useState(false);
// Load fonts
const baseAssetsPath = "./assets/fonts";
const fonts_by_path = {
"DMSans-Regular": require(`${baseAssetsPath}/DMSans-Regular.ttf`),
"DMSans-Bold": require(`${baseAssetsPath}/DMSans-Bold.ttf`),
"DMSans-BoldItalic": require(`${baseAssetsPath}/DMSans-BoldItalic.ttf`),
"DMSans-Medium": require(`${baseAssetsPath}/DMSans-Medium.ttf`),
"DMSans-MediumItalic": require(`${baseAssetsPath}/DMSans-MediumItalic.ttf`),
"DMSans-Italic": require(`${baseAssetsPath}/DMSans-Italic.ttf`),
};
const [fontsLoaded] = useFonts(fonts_by_path);
// Load images
console.log(numberOfImagesLoaded);
const imagesAreLoaded = numberOfImagesLoaded > 2;
// const imagesAreLoaded = true;
if (fontsLoaded && imagesAreLoaded && !appIsReady) {
setAppIsReady(true);
}
return appIsReady;
};
export default useAppIsReady;
Here is a link to the repo
https://github.com/Bijig0/loading-imgs-testing

using Onclick, fetch api data in react native

I am new to React Native.
I am facing an issue with this view. Basically it is something like this when you click a button it generates any random number, now this random number becomes an id and it goes to at the end of the API url, And using this new API - with ID at the end of it. - data gets fetched. Now i've divided this task in two parts generating random number code (i.e. snippet 1) and fetching data from api ( i.e. snippet 2). As of now, I don't know how to combine them because i am new to react native so a little help here would be appreciated from anyone.
Snipppet 1
import { StyleSheet, View, Button, Text } from 'react-native';
export default class MyProject extends Component {
constructor(){
super();
this.state={
// This is our Default number value
NumberHolder : 0
}
}
GenerateRandomNumber=()=>
{
var RandomNumber = Math.floor(Math.random() * 5000) + 1 ;
this.setState({
NumberHolder : RandomNumber
})
}
render() {
return (
<View style={styles.MainContainer} >
<Text style={{marginBottom: 10, fontSize: 20}}>{this.state.NumberHolder}</Text>
<Button title="Generate Random Number" onPress={this.GenerateRandomNumber} />
</View>
);
}
}
const styles = StyleSheet.create(
{
MainContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
});
Snippet 2
import React, { useState } from "react";
import { Box, FlatList, Center, NativeBaseProvider, Button } from "native-base";
import { StyleSheet, View, ActivityIndicator, Text, TouchableOpacity, Image } from 'react-native';
export default function MyFUnction() {
const [data, setData] = useState(null);
const [visible, setVisible] = useState(true);
const fetchData = async () => {
const resp = await fetch("https://jsonplaceholder.typicode.com/photos/7");
const data = await resp.json();
setData(data);
setVisible(false);
};
const renderItem = ({ item }) => {
return (
<TouchableOpacity style={styles.list}>
<Text>{item.title}</Text>
</TouchableOpacity>
);
};
return (
<NativeBaseProvider>
<Center flex={1}>
{visible && <Button onPress={() => fetchData()}>Press</Button>}
{data && (
<FlatList
data={data}
renderItem={(item) => this.renderItem(item)}
keyExtractor={(item) => item.id.toString()}
/>
)}
</Center>
</NativeBaseProvider>
);
}
const styles = StyleSheet.create({
list: {
paddingVertical: 4,
margin: 5,
backgroundColor: '#fff',
},
});
Thanks in advance!!
I think you must understand components clearly! React is component based! But your case is not 2 components! You have a component for fetching api and showing in list! Generating a random number is not a component, but it is a method(or function) in your list component! I think it is better to use one component for list and wrap a function to it for generating random number.
import React, { useState } from "react";
import { Box, FlatList, Center, NativeBaseProvider, Button } from "native-base";
import { StyleSheet, View, ActivityIndicator, Text, TouchableOpacity, Image } from 'react-native';
export default function MyFUnction() {
const [data, setData] = useState(null);
const [visible, setVisible] = useState(true);
const generatRandomNumber = () => {
return Math.floor(Math.random() * 5000) + 1
}
const fetchData = async () => {
const resp = await fetch(`https://jsonplaceholder.typicode.com/photos/${generatRandomNumber()}`);
const data = await resp.json();
setData(data);
setVisible(false);
};
const renderItem = ({ item }) => {
return (
<TouchableOpacity style={styles.list}>
<Text>{item.title}</Text>
</TouchableOpacity>
);
};
return (
<NativeBaseProvider>
<Center flex={1}>
{visible && <Button onPress={() => fetchData()}>Press</Button>}
{data && (
<FlatList
data={data}
renderItem={(item) => this.renderItem(item)}
keyExtractor={(item) => item.id.toString()}
/>
)}
</Center>
</NativeBaseProvider>
);
}
const styles = StyleSheet.create({
list: {
paddingVertical: 4,
margin: 5,
backgroundColor: '#fff',
},
});
But if you want to passing data between components you are have, it is not related to function or class component and you can pass data between them with props! So your code like this:
Random Number Component
import { StyleSheet, View, Button, Text } from 'react-native';
export default class MyProject extends Component {
constructor(props){ //edited
super(props); //edited
this.state={
// This is our Default number value
NumberHolder : 0
}
}
GenerateRandomNumber=()=>
{
var RandomNumber = Math.floor(Math.random() * 5000) + 1 ;
this.props.randomNumber(RandomNumber)
}
render() {
return (
<View style={styles.MainContainer} >
<Text style={{marginBottom: 10, fontSize: 20}}>{this.state.NumberHolder}</Text>
<Button title="Generate Random Number" onPress={this.GenerateRandomNumber} />
</View>
);
}
}
const styles = StyleSheet.create(
{
MainContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
});
Your list component:
import React, { useState } from "react";
import { Box, FlatList, Center, NativeBaseProvider, Button } from "native-base";
import { StyleSheet, View, ActivityIndicator, Text, TouchableOpacity, Image } from 'react-native';
// import MyProject
export default function MyFUnction() {
const [data, setData] = useState(null);
const [visible, setVisible] = useState(true);
const [number, setNumber] = useState(null);
const fetchData = async () => {
const resp = await fetch(`https://jsonplaceholder.typicode.com/photos/${number}`);
const data = await resp.json();
setData(data);
setVisible(false);
};
const renderItem = ({ item }) => {
return (
<TouchableOpacity style={styles.list}>
<Text>{item.title}</Text>
</TouchableOpacity>
);
};
return (
<NativeBaseProvider>
<Center flex={1}>
<MyProject radomNumber={(number) => setNumber(number)}
{visible && <Button onPress={() => fetchData()}>Press</Button>}
{data && (
<FlatList
data={data}
renderItem={(item) => this.renderItem(item)}
keyExtractor={(item) => item.id.toString()}
/>
)}
</Center>
</NativeBaseProvider>
);
}
const styles = StyleSheet.create({
list: {
paddingVertical: 4,
margin: 5,
backgroundColor: '#fff',
},
});
thanks everyone for helping me.
here i am posting answer to my question, if anybody in future need an answer.
import React, { useEffect, useState, Component } from 'react';
import { StyleSheet, View, Button, FlatList, Text, Image } from 'react-native';
export default class MyProject extends Component {
constructor(){
super();
this.state={
// This is our Default number value
NumberHolder : 1,
books: []
}
}
GenerateRandomNumber=()=>
{
var RandomNumber = Math.floor(Math.random() * 5000) + 1;
fetch(`https://jsonplaceholder.typicode.com/photos/${RandomNumber}`)
.then((response) => response.json())
.then(booksList => {
this.setState({ books: booksList });
});
this.setState({
NumberHolder : RandomNumber
})
}
render() {
let Image_Http_URL ={ uri: 'https://reactnativecode.com/wp-content/uploads/2017/05/react_thumb_install.png'};
return (
<View style={styles.MainContainer} >
<Text style={{marginBottom: 10, fontSize: 20}}>{this.state.NumberHolder}</Text>
<Image
style={{width: '100%', height: 200,resizeMode : 'stretch' }}
source={{uri: this.state.books.url}}
/>
<Text style={{marginBottom: 10, fontSize: 12}}>{this.state.books.title}</Text>
<Text style={{marginBottom: 10, fontSize: 12}}>{this.state.books.url}</Text>
<Text style={{marginBottom: 10, fontSize: 12}}>{this.state.books.thumbnailUrl}</Text>
<Button title="Generate Random Number" onPress={this.GenerateRandomNumber} />
</View>
);
}
}
const styles = StyleSheet.create(
{
MainContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
});

TypeError: null is not an object (evaluating ''this.state.torchon')

I don't know what am doing wrong in the code below...I want to toggle flash light on/off during camera capturing, but my code is not working, I tried binding the state in different ways but is still not working for me...Below is my code. Please I need help on how to get this working.
import React, { Component } from 'react';
import { View, StyleSheet, Text, TouchableOpacity } from 'react-native';
import { RNCamera } from 'react-native-camera';
import RNFetchBlob from 'rn-fetch-blob';
import Icon from 'react-native-vector-icons/Ionicons';
class cameraComponent extends Component {
toggleTorch()
{
let tstate = this.state.torchon;
if (tstate == RNCamera.Constants.FlashMode.off){
tstate = RNCamera.Constants.FlashMode.torch;
} else {
tstate = RNCamera.Constants.FlashMode.off;
}
this.setState({torchon:tstate})
}
takePicture = async () => {
if(this.camera) {
const options = { quality: 0.5, base64: true };
const data = await this.camera.takePictureAsync(options);
console.log(data.base64)
const path = `${RNFetchBlob.fs.dirs.CacheDir}/test.png`;
console.log('path', path)
try {
RNFetchBlob.fs.writeFile(path, data.base64, 'base64')
}
catch(error) {
console.log(error.message);
}
}
};
render() {
return (
<View style={styles.container}>
<RNCamera
ref = {ref=>{
this.camera=ref;
}}
style={styles.preview}
flashMode={this.state.torchon}
// type = {RNCamera.Constants.Type.back}
>
</RNCamera>
<View style={{ flex: 0, flexDirection: 'row', justifyContent: 'center' }}>
<TouchableOpacity onPress={this.takePicture.bind(this)} style={styles.captureBtn} />
</View>
<TouchableOpacity style={styles.toggleTorch} onPress={this.toggleTorch.bind(this)}>
{ this.state.torchon == RNCamera.Constants.FlashMode.off? (
<Image style={styles.iconbutton} source={require('../images/flashOff.png')} />
) : (
<Image style={styles.iconbutton} source={require('../images/flashOn.png')} />
)
}
</TouchableOpacity>
</View>
);
};
}
export default cameraComponent;
You have not initialized the state anywhere and when you access this.state.torchon it throws the error because this.state is null.
You have to initialize the state.
class cameraComponent extends Component {
this.state={ torchon:RNCamera.Constants.FlashMode.off };
toggleTorch=()=>
{
let tstate = this.state.torchon;
if (tstate == RNCamera.Constants.FlashMode.off){
tstate = RNCamera.Constants.FlashMode.torch;
} else {
tstate = RNCamera.Constants.FlashMode.off;
}
this.setState({torchon:tstate})
}
You can also initialize the state inside the constructor as well.

React Native Issue

I am building a react native app that uses the Wordpress api. I am having problems displaying the cart and receive this error.
Object {} error [Error: Request failed with status code 404]
undefined
I have tried everything and have figures it might be a problem with Axios...
Please advise me on what I can do...
CartAction.js
import * as types from '../constants/ActionTypes';
import CartApi from '../api/CartApi';
export function getCart() {
return (dispatch) => {
return CartApi.getCart().then(cart => {
dispatch(getCartSuccess(cart));
}).catch(err => {
//TODO:get correct error msg
console.log(err.error);
})
};
}
function getCartSuccess(cart) {
return {
type: types.GET_CART_SUCCESS,
cart
};
}
export function addToCart(product, quantity) {
return (dispatch) => {
return CartApi.addToCart(product, quantity).then(cartUpdate => {
dispatch(addToCartSuccess(cartUpdate));
}).catch(err => {
//TODO:get correct error msg
console.log('error',err);
})
};
}
function addToCartSuccess(cartUpdate) {
return {
type: types.ADD_TO_CART_SUCCESS,
cartUpdate
};
}
CartPage.js
import React from 'react'
import { StyleSheet, Text, View, FlatList, Image } from 'react-native'
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as CartAction from '../../actions/CartAction';
class CartPage extends React.Component {
constructor(props) {
super(props);
this.state = {
cart: {}
}
}
componentDidMount() {
this.props.CartAction.getCart();
}
_keyExtractor = (item, index) => item.key;
render() {
console.log(this.props.cart)
const cartObject = this.props.cart;
var cartArray = [];
Object.keys(cartObject).forEach(function(key) {
cartArray.push(cartObject[key]);
});
const Items = <FlatList contentContainerStyle={styles.list}
data={cartArray}
keyExtractor={this._keyExtractor}
renderItem={({ item }) =>
// <TouchableHighlight style={{width:'50%'}} onPress={() => navigate("Product", { product: item })} underlayColor="white">
<View style={styles.lineItem} >
<Image style={styles.image} source={{uri: item.product_image}} />
<Text style={styles.text}>{item.product_name}</Text>
<Text style={styles.text}>{item.quantity}</Text>
</View>
// </TouchableHighlight>
}
/>;
return (
<View style={styles.container}>
{Items}
</View>
)
}
}
const styles = StyleSheet.create({
lineItem: {
flexDirection: 'row'
},
list: {
flexDirection: 'column'
},
image: {
width: 50,
height: 50
},
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize: 20,
padding: 5
}
})
function mapStateToProps(state) {
return {
cart: state.cart
};
}
function mapDispatchToProps(dispatch) {
return {
CartAction: bindActionCreators(CartAction, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(CartPage);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

navigate to another screen from tab-view screen not working

following is my code:- posting full code
index.android.js
import React, { Component } from 'react';
import { AppRegistry, Text, StyleSheet, View, NetInfo, Alert, AsyncStorage } from 'react-native';
import Splash from './app/screens/Splash'
import { StackNavigator } from 'react-navigation'
import Login from './app/screens/Login'
import Register from './app/screens/Register'
import Check from './app/screens/Check'
import Qwerty from './app/screens/Qwerty'
import Home from './app/screens/Home'
var STORAGE_KEY = 'token';
var DEMO_TOKEN;
class Splashscreen extends React.Component {
static navigationOptions = {
header: null
};
async componentDidMount() {
const { navigate } = this.props.navigation;
var DEMO_TOKEN = await AsyncStorage.getItem(STORAGE_KEY);
if (DEMO_TOKEN === undefined) {
navigate("Login");
} else if (DEMO_TOKEN === null) {
navigate("Splash");
} else {
navigate("Temp");
}
};
render() {
const { navigate } = this.props.navigation;
return(
<View style={styles.wrapper}>
<View style={styles.titlewrapper}>
<Text style={styles.title}> Loding... </Text>
</View>
</View>
);
}
}
const Section = StackNavigator({
Root: {screen: Splashscreen},
Splash: { screen: Splash },
Login: { screen: Login },
Registerscreen: { screen: Register },
Temp: { screen: Check },
Qwerty:{screen: Qwerty},
Home:{screen: Home},
});
AppRegistry.registerComponent('shopcon', () => Section);
here i can navigate properly without any error Now,
This is my tab.js => Here i given three tabs (mainly working in first home.js)
import React, { PureComponent } from 'react';
import { Animated, StyleSheet,View } from 'react-native';
import { TabViewAnimated, TabBar } from 'react-native-tab-view';
import { StackNavigator } from 'react-navigation';
import Qwerty from './Qwerty';
import Home from './Home';
//import Login from './Login'
import type { NavigationState } from 'react-native-tab-view/types';
type Route = {
key: string,
title: string,
};
type State = NavigationState<Route>;
class Tab extends PureComponent<void, *, State> {
static navigationOptions = {
header: null
};
state: State = {
index: 0,
routes: [
{ key: '1', title: 'Home' },
{ key: '2', title: 'Shops' },
{ key: '3', title: 'Bookmark' },
],
};
_first: Object;
_second: Object;
_third: Object;
_handleIndexChange = index => {
this.setState({
index,
});
};
_renderLabel = props => ({ route, index }) => {
const inputRange = props.navigationState.routes.map((x, i) => i);
const outputRange = inputRange.map(
inputIndex => (inputIndex === index ? '#fff' : '#222')
);
const color = props.position.interpolate({
inputRange,
outputRange,
});
return (
<View>
<Animated.Text style={[styles.label, { color }]}>
{route.title}
</Animated.Text>
</View>
);
};
_renderHeader = props => {
return (
<TabBar
{...props}
pressColor="#999"
// onTabPress={this._handleTabItemPress}
renderLabel={this._renderLabel(props)}
indicatorStyle={styles.indicator}
tabStyle={styles.tab}
style={styles.tabbar}
/>
);
};
_renderScene = ({ route }) => {
switch (route.key) {
case '1':
return (
<Home
ref={el => (this._first = el)}
style={[styles.page, { backgroundColor: '#E3F4DD' }]}
/>
);
case '2':
return (
<Qwerty
ref={el => (this._second = el)}
style={[styles.page, { backgroundColor: '#E6BDC5' }]}
initialListSize={1}
/>
);
case '3':
return (
<Qwerty
ref={el => (this._third = el)}
style={[styles.page, { backgroundColor: '#EDD8B5' }]}
initialListSize={1}
/>
);
default:
return null;
}
};
render() {
return (
<TabViewAnimated
style={[styles.container, this.props.style]}
navigationState={this.state}
renderScene={this._renderScene}
renderHeader={this._renderHeader}
onIndexChange={this._handleIndexChange}
// onRequestChangeTab={this._handleIndexChange}
lazy
/>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
indicator: {
backgroundColor: '#fff',
},
label: {
fontSize: 18,
fontWeight: 'bold',
margin: 8,
},
tabbar: {
backgroundColor: '#ff6600',
},
tab: {
opacity: 1,
// width: 140,
},
page: {
backgroundColor: '#f9f9f9',
},
});
export default Tab;
This is Home.js => It is running well if i am using it directly but not running when using it in Tab.js
GoPressed(navigate){
navigate("Registerscreen");
}
render() {
const { navigate } = this.props.navigation;
contents = this.state.qwerty.data.map((item) => {
return (
<View>
{item.p1.shareproductid ? <TouchableHighlight onPress={() => this.GoPressed(navigate)} style={styles.button}>
<Text style={styles.buttonText}>
Go
</Text>
</TouchableHighlight> : null }
<Text>
{item.p1.content}
</Text>
</View>
);
});
return (
<ScrollView style={styles.container}>
{contents}
</ScrollView>
);
}
I am trying to navigate on Register screen after Go button pressed, But here it shows me error. I have used same navigation method before they works correctly but here it gives error. please show where i am going wrong?
How to navigate to any other(not these three screens of tab-view ) screen from tab-view?
I tried running Home.js in other way means not using in tab view then it is running and navigation also works but when i am calling Home.js in tab-view i.e in Tab.js then it showing error as in screenshot.
Seems like you're navigating to the wrong screen name.
This should do it.
GoPressed(navigate){
navigate("Registerscreen");
}
I honestly can't test out your code as it'll take too much time.
How about you check out this simple working example of what your looking for and match it with your code.
Go the Settings tab and then you can click on the button to navigate to the other Registerscreen which is not in the Tabs.
https://snack.expo.io/HJ5OqS5qZ

Categories