Invariant Violation in React Native: Text strings must be rendered within a <Text> component - react-native

I'm working on a React-Native project with REST APis, and I've currently got an invariant violation error. I've experienced this before, but I can't quite figure out what is causing it and how to fix it. If someone could point me in the right direction, I would really appreciate it! The full error is pictured below, and appears to be referencing a number of tags in the code, so I'm unsure exactly where it is originating. Thank you for reading, and thanks in advance!
The code is here:
import React, { Component } from 'react'
import { View, Text, Image, StyleSheet, FlatList} from 'react-native';
import * as Font from 'expo-font';
import styled from 'styled-components';
import dimensions from '../components/ScreenSize';
import colours from '../components/Colours';
import { Audio } from 'expo-av';
import { TouchableHighlight } from 'react-native-gesture-handler';
const client_id = {Client_ID}
const client_secret = {Client_Secret}
const item = ({item}) => (
<View style={{ flex:1, flexDirection: 'column', margin:1}}>
<TouchableHighlight onPress={() => this.fetchTracks(item.id)}>
<View>
<Text>{item.name}</Text>/>
</View>
</TouchableHighlight>
</View>
)
export default class HomeScreen extends React.Component {
state={
fontsLoaded:false,
}
async componentDidMount() {
await Font.loadAsync({
'montserrat-regular': require('../assets/fonts/Montserrat/Montserrat-Regular.ttf'),
'montserrat-light': require('../assets/fonts/Montserrat/Montserrat-Light.ttf'),
'montserrat-semibold': require('../assets/fonts/Montserrat/Montserrat-SemiBold.ttf'),
'montserrat-bold': require('../assets/fonts/Montserrat/Montserrat-Bold.ttf'),
}
).then(() => this.setState({ fontsLoaded:true }))
this.getToken();
this.setAudio();
}
constructor (props) {
super(props)
this.playbackInstance=null;
this.state = {
playing:false,
token: '',
DATA:[],
};
}
setAudio=() => {
Audio.setAudioModeAsync({
allowsRecordingIOS:false,
interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
playsInSilentModeIOS: true,
shouldDuckAndroid: true,
interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
playThroughEarpieceAndroid: false,
});
}
componentDidCatch(error, info)
{
console.log(error, info.componentStack);
}
getToken = async() =>
{
try
{
const getspotifytoken = await fetch("https://accounts.spotify.com/api/token",
{
method:'POST',
body: `grant_type=client_credentials&client_id=${client_id}&client_secret=${client_secret}`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
const spotifytoken = await getspotifytoken.json();
this.setState({
token: spotifytoken.access_token
});
console.log(this.state.token);
}
catch(err)
{
console.log("Error fetching data", err);
}
}
search = async () => {
try
{
console.log("Searching: mood")
const spotifyApiCall = await fetch(`https://api.spotify.com/v1/browse/categories/mood/playlists?`, {
headers: {
Accept: 'application/json',
Authorization: `Bearer ${this.state.token}`,
"Content-Type":'application/json'
}
})
const spotify = await spotifyApiCall.json();
console.log("Items", spotify);
this.setState({
DATA: spotify.playlists.items,
})
}
catch (err)
{
console.log("Error fetching data", err);
}
}
fetchTracks = async (playlistId) => {
console.log('Playlist ', playlistId)
try
{
const getplaylist = await fetch(`https://api.spotify.com/v1.playlist/${playlistId}`,
{
method:'GET',
headers: {
Accept:"application/json",
Authorization:`Bearer ${this.state.token}`,
"Content-Type":"application/json"
}
});
const playlist = await getplaylist.json();
console.log('music ', playlist.tracks.items[0].preview_url);
}
catch (err)
{
console.log("Error fetching data ", err);
}
}
async _loadNewPlaybackInstance(playing, track) {
if(this.playbackInstance != null)
{
await this.playbackInstance.unloadAsync();
this.playbackInstance.setOnPlaybackStatusUpdate(null);
this.playbackInstance = null;
}
const source = {uri: track};
const initialStatus = {
shouldPlay: true,
rate: 1.0,
shouldCorrectPitch: true,
volume: 1.0,
isMuted: false
};
const {sound, status} = await Audio.Sound.createAsync(
source.initialStatus);
this.playbackInstance=sound;
this.playbackInstance.setIsLoopingAsync(false);
this.playbackInstance.playAsync();
if (this.state.selected === playlistId) {
console.log("Playing, so stop");
this.setState({selected:null});
this.playbackInstance.pauseAsync();
return;
}
this.setState({ selected:playlistId});
this._loadNewPlaybackInstance(true, playlist.tracks.items[0].preview_url);
}
render() {
if(!this.state.fontsLoaded ) {
return null
}
return (
<Container>
<Titlebar>
<Title>Music</Title>
</Titlebar>
<HeaderBar2>
<TouchableHighlight onPress={() => this.search()}>
<Header2>Playlists for your Mood</Header2>
</TouchableHighlight>
</HeaderBar2>
<View style={styles.MainContainer}>
{
this.state.DATA.length == 0 &&
<Text style={{padding:10, color:'#D3D3D3'}}/>
}
<FlatList
data = {this.state.DATA}
renderItem={item}
keyExtractor = {item.id}
numColumns={2}
extraData = {this.state}
/>
</View>
</Container>
);
}
}

I think u just have a little typo ..
check this line: <Text>{item.name}</Text>/>
change the last Text to </Text>

Related

How to load contact details into multi select drop down in react native?

I am creating a react native app to load phone book contacts to my app using this library. I loaded contact correctly in my app. Now I wanted to load these contact details in to multi select drop down. I used react-native-multiple-select to load contact using this library. But I am not be able load contact into this library.
The UI that I need to load contact details.
This is what I tried,
import React, {Component} from 'react';
import {
View,
Text,
TouchableOpacity,
FlatList,
ActivityIndicator,
Image,
TextInput,
PermissionsAndroid,
Platform,
Modal,
TouchableHighlight,
Alert,
} from 'react-native';
import ContactsLib from 'react-native-contacts';
import {styles} from '../src/HomeTabs/ContactStyles';
import PropTypes from 'prop-types';
import {Header} from 'react-native-elements';
import MultiSelect from 'react-native-multiple-select';
//Import MultiSelect library
export class Tab2 extends Component {
constructor(props) {
super(props);
this.state = {
contactList: [],
selectedContact: [],
text: '',
isLoading: true,
show: false,
modalVisible: false,
};
this.arrayholder = [];
}
async componentDidMount() {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
{
title: 'App Contact Permission',
message: 'This App needs access to your contacts ',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
},
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
this.getListOfContacts();
this.showconsole();
} else {
this.setState({isLoading: false});
this.getOtherContacts();
}
} catch (err) {
this.setState({isLoading: false});
}
} else {
ContactsLib.checkPermission((err, permission) => {
if (permission === 'denied') {
this.setState({isLoading: false});
this.getOtherContacts();
} else {
this.getListOfContacts();
}
});
}
}
// Mics Method
getOtherContacts = () => {
const {otherContactList} = this.props;
const arrFinal = [];
if (otherContactList.length > 0) {
otherContactList.map(listItem => {
arrFinal.push(listItem);
});
}
arrFinal.map((listItem, index) => {
listItem.isSelected = false;
listItem.id = index;
});
this.setState({contactList: arrFinal, isLoading: false});
this.arrayholder = arrFinal;
};
getListOfContacts = () => {
const {otherContactList} = this.props;
const arrFinal = [];
ContactsLib.getAll((err, contacts) => {
if (err) {
throw err;
}
contacts.map(listItem => {
arrFinal.push({
fullname: listItem.givenName + ' ' + listItem.familyName,
phoneNumber:
listItem.phoneNumbers.length > 0
? listItem.phoneNumbers[0].number
: '',
avatar: listItem.thumbnailPath,
});
});
if (otherContactList.length > 0) {
otherContactList.map(listItem => {
arrFinal.push(listItem);
});
}
arrFinal.map((listItem, index) => {
listItem.isSelected = false;
listItem.id = index;
});
this.setState({contactList: arrFinal, isLoading: false});
this.arrayholder = arrFinal;
});
};
getSelectedContacts = () => {
const {selectedContact} = this.state;
return selectedContact;
};
checkContact = item => {
const {onContactSelected, onContactRemove} = this.props;
let arrContact = this.state.contactList;
let arrSelected = this.state.selectedContact;
arrContact.map(listItem => {
if (listItem.id === item.id) {
listItem.isSelected = !item.isSelected;
}
});
if (item.isSelected) {
arrSelected.push(item);
if (onContactSelected) {
onContactSelected(item);
}
} else {
if (onContactRemove) {
onContactRemove(item);
}
arrSelected.splice(arrSelected.indexOf(item), 1);
}
this.setState({contactList: arrContact, selectedContact: arrSelected});
};
checkExist = item => {
const {onContactRemove} = this.props;
let arrContact = this.state.contactList;
let arrSelected = this.state.selectedContact;
arrContact.map(listItem => {
if (listItem.id === item.id) {
listItem.isSelected = false;
}
});
if (onContactRemove) {
onContactRemove(item);
}
arrSelected.splice(arrSelected.indexOf(item), 1);
this.setState({contactList: arrContact, selectedContact: arrSelected});
};
SearchFilterFunction = text => {
let newArr = [];
this.arrayholder.map(function(item) {
const itemData = item.fullname.toUpperCase();
const textData = text.toUpperCase();
if (itemData.indexOf(textData) > -1) {
newArr.push(item);
}
});
this.setState({
contactList: newArr,
text: text,
});
};
//Render Method
_renderItem = ({item}) => {
const {viewCheckMarkStyle} = this.props;
return (
<TouchableOpacity onPress={() => this.checkContact(item)}>
<View style={styles.viewContactList}>
<Image
source={
item.avatar !== ''
? {uri: item.avatar}
: require('../images/user.png')
}
style={styles.imgContactList}
/>
<View style={styles.nameContainer}>
<Text style={styles.txtContactList}>{item.fullname}</Text>
<Text style={styles.txtPhoneNumber}>{item.phoneNumber}</Text>
</View>
{item.isSelected && (
<Image
source={require('../images/check-mark.png')}
style={[styles.viewCheckMarkStyle, viewCheckMarkStyle]}
/>
)}
</View>
</TouchableOpacity>
);
};
state = {
//We will store selected item in this
selectedItems: [],
};
onSelectedItemsChange = selectedItems => {
this.setState({selectedItems});
//Set Selected Items
};
render() {
const {selectedItems} = this.state;
const {searchBgColor, searchPlaceholder, viewSepratorStyle} = this.props;
return (
<View style={styles.container}>
<MultiSelect
hideTags
items={this.contactList}
uniqueKey="id"
ref={component => {
this.multiSelect = component;
}}
onSelectedItemsChange={this.onSelectedItemsChange}
selectedItems={selectedItems}
selectText="Select Contacts"
searchInputPlaceholderText="Search Contacts..."
onChangeInput={text => console.log(text)}
tagRemoveIconColor="#ff0000"
tagBorderColor="#48d22b"
tagTextColor="#000"
selectedItemTextColor="#48d22b"
selectedItemIconColor="#48d22b"
itemTextColor="#000"
displayKey="name"
searchInputStyle={{color: '#48d22b'}}
submitButtonColor="#48d22b"
submitButtonText="Submit"
/>
<View>
{this.multiSelect &&
this.multiSelect.getSelectedItemsExt(selectedItems)}
</View>
{this.state.isLoading && (
<View style={styles.loading}>
<ActivityIndicator animating={true} size="large" color="gray" />
</View>
)}
</View>
);
}
}
Tab2.propTypes = {
otherContactList: PropTypes.array,
viewCloseStyle: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.object,
]),
viewCheckMarkStyle: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.object,
]),
sepratorStyle: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.object,
]),
viewSepratorStyle: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.object,
]),
searchBgColor: PropTypes.string,
searchPlaceholder: PropTypes.string,
onContactSelected: PropTypes.func,
onContactRemove: PropTypes.func,
};
Tab2.defaultProps = {
otherContactList: [],
viewCloseStyle: {},
viewCheckMarkStyle: {},
sepratorStyle: {},
viewSepratorStyle: {},
searchBgColor: 'rgb(202,201,207)',
searchPlaceholder: 'Search...',
onContactSelected: () => {},
onContactRemove: () => {},
};
export default Tab2;
your multiselect should be given the contacts. Try stripping out anything nonessential from your example
...
render() {
...
return (
...
<MultiSelect
items={this.state.contactList}
...
/>
...
);
}

React Native image picker is showing image too slow after successfully uploading

after uploading image successfully the uploaded image is taking time to show ?
anyone knows anything about it?
here is my code
_onPressEdit = () => {
ImagePicker.showImagePicker(options, response => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
} else {
this._uploadImage(response.uri);
}
});
};
here is my full code
import React, {PureComponent} from 'react';
import {View, Text, Image, PermissionsAndroid, Platform} from 'react-native';
import {connect} from 'react-redux';
import ImagePicker from 'react-native-image-picker';
import styles from './styles';
import {Images, Styles, Language, Colors} from '#theme';
import {Wrapper, Input, ButtonView} from '#components';
import {TextInputField} from '#customComponents';
import {Navigator} from '#services';
import StarRating from 'react-native-star-rating';
import Header from '../Header';
import Footer from '../Footer';
import {uploadImage, editProfile} from '../../../actions/UserActions';
import {BASE_URL_PHOTO} from '../../../config/WebService';
import {selectUserData} from '../../../selectors/userSelector';
import {UserPresenter} from '../../../presenter';
import {Util} from '../../../utils';
const options = {
storageOptions: {
skipBackup: true,
path: 'images',
},
};
class Profile extends PureComponent {
constructor(props) {
super(props);
const {firstName, lastName, email, mobile, image, id} = this.props.user;
this.state = {
id,
firstName,
lastName,
email,
mobile,
image,
errors: {},
};
}
onStarRatingPress(rating) {
this.setState({
starCount: rating,
});
}
checkAllPermissions = async () => {
try {
await PermissionsAndroid.requestMultiple([
PermissionsAndroid.PERMISSIONS.CAMERA,
PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
]);
if (
(await PermissionsAndroid.check('android.permission.CAMERA')) &&
(await PermissionsAndroid.check('android.permission.CAMERA')) &&
(await PermissionsAndroid.check('android.permission.CAMERA'))
) {
this._onPressEdit();
return true;
} else {
console.log('all permissions denied');
return false;
}
} catch (err) {
console.warn(err);
}
};
_onPressEdit = () => {
ImagePicker.showImagePicker(options, response => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled image picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
} else {
this._uploadImage(response.uri);
}
});
};
_uploadImage = image => {
const {uploadImage} = this.props;
const {id} = this.props.user;
UserPresenter.sendUploadAvatarRequest(
uploadImage,
image,
id,
this._onSuccessImageUpload,
);
};
_onSuccessImageUpload = uri => {
this.setState({
image: uri,
});
};
_onChangeText = (key, value) => {
this.setState(
{
[key]: value,
},
() => console.log(this.state),
);
};
_validateForm = () => {
const {firstName, lastName, mobile} = this.state;
const errors = UserPresenter.getEditProfileErrors(
firstName,
lastName,
mobile,
);
this.setState({errors});
return Util.isEmpty(errors);
};
_onPressSave = () => {
const {firstName, lastName, mobile, image} = this.state;
const {id} = this.props.user;
const {editProfile} = this.props;
if (this._validateForm()) {
UserPresenter.sendEditProfileRequestStepOne(
editProfile,
id,
firstName,
lastName,
mobile,
image,
this._onSuccessSave,
);
}
};
_onSuccessSave = () => {
// Navigator.pop();
Navigator.goBack();
};
_onPressNext = () => {
if (this._validateForm()) {
Navigator.navigate('EditProfileServices', {data: this.state});
}
};
onPressFooterBtn = () => {
Navigator.navigate('EditProfileServices');
};
renderStarRating() {
const {rating} = this.props.user;
return (
<StarRating
starSize={24}
starStyle={styles.starStyle}
halfStarEnabled={true}
halfStarColor={Colors.textWhiteTwo}
emptyStarColor={Colors.textWhiteTwo}
disabled={true}
maxStars={5}
rating={rating}
selectedStar={rating => this.onStarRatingPress(rating)}
/>
);
}
renderEditFields() {
const {firstName, lastName, email, mobile, errors} = this.state;
return (
<View>
<TextInputField
title={Language.firstName}
placeholder={Language.Andrew}
value={firstName}
onChangeText={text => this._onChangeText('firstName', text)}
error={errors.firstName}
/>
<TextInputField
title={Language.lastName}
placeholder={Language.Crammer}
value={lastName}
onChangeText={text => this._onChangeText('lastName', text)}
error={errors.lastName}
/>
<TextInputField
title={Language.email}
keyboardType={'email-address'}
placeholder={Language.andrewCrammerEmail}
value={email}
onChangeText={text => this._onChangeText('email', text)}
error={errors.email}
editable={false}
/>
<TextInputField
title={Language.phone}
keyboardType={'phone-pad'}
placeholder={Language.EditProfilePhonePlaceholder}
value={mobile}
onChangeText={text => this._onChangeText('mobile', text)}
error={errors.mobileNumber}
/>
{/* <Input
label={Language.changePassword}
secureTextEntry={true}
placeholder={Language.EditProfileChangePassword}
/> */}
</View>
);
}
renderBody() {
const {rating} = this.props.user;
const {image} = this.state;
return (
<View style={Styles.paddingHorizontal}>
<View
style={[
Styles.flexDirectionRow,
Styles.alignItemsCenter,
styles.mb_30,
]}>
<View style={styles.editProfileImgWrap}>
<Image
style={styles.imgStyle}
source={{uri: `${BASE_URL_PHOTO}${image}`}}
/>
<ButtonView
isBackgroundRipple
onPress={
Platform.OS === 'android'
? this.checkAllPermissions
: this._onPressEdit
}
style={[Styles.positionAbsolute, styles.editWrap]}>
<Text style={styles.edit}>{Language.edit}</Text>
</ButtonView>
</View>
<View>
<Text style={styles.textStyle}>{Language.ProfilePicture}</Text>
</View>
</View>
<View style={styles.starStyleWrap}>
{this.renderStarRating()}
<Text style={styles.starRatingText}>{rating}</Text>
</View>
<View>{this.renderEditFields()}</View>
</View>
);
}
renderHeader() {
return <Header onPressSave={this._onPressSave} />;
}
renderFooter() {
return <Footer onPressNext={this._onPressNext} step={1} />;
}
//Render
render() {
return (
<Wrapper
header={this.renderHeader()}
footer={this.renderFooter()}
isFetching={this.props.isFetching}
isAbsolute
mainContainerStyle={Styles.paddingHorizontalNone}
isScrollView>
{this.renderBody()}
</Wrapper>
);
}
}
const mapStateToProps = state => {
return {
user: selectUserData(state.user),
isFetching: state.user.isFetching,
};
};
const actions = {uploadImage, editProfile};
export default connect(mapStateToProps, actions)(Profile);
issue solved
just compress your image size so it wont take time to appear
here is the code
const options = {
title: 'Select Picture',
storageOptions: {
skipBackup: true,
path: 'images',
},
maxWidth: 500,
maxHeight: 500,
quality: 0.5,
};
previous code was
const options = {
storageOptions: {
skipBackup: true,
path: 'images',
},
};

react native setInterval cannot read property apply

I am new in react native I am trying to render the count of unread notification for that I called my API in HOC it is working fine for initial few seconds but after that, I started to get the below error
func.apply is not a function
below is my code
import React, { Component } from "react";
import PropTypes from "prop-types";
import { Modal, View } from "react-native";
import { themes } from "./constants";
import { AsyncStorage } from "react-native";
export default (OriginalComponent, animationType) =>
class extends Component {
static propTypes = {
handleFail: PropTypes.func,
theme: PropTypes.string,
visible: PropTypes.bool
};
state = {
modalVisible: true
};
static getDerivedStateFromProps({ visible }) {
if (typeof visible === "undefined") {
setInterval(
AsyncStorage.getItem("loginJWT").then(result => {
if (result !== null) {
result = JSON.parse(result);
fetch(serverUrl + "/api/getUnreadNotificationsCount", {
method: "GET",
headers: {
Authorization: "Bearer " + result.data.jwt
}
})
.then(e => e.json())
.then(function(response) {
if (response.status === "1") {
if (response.msg > 0) {
AsyncStorage.setItem(
"unreadNotification",
JSON.stringify(response.msg)
);
} else {
AsyncStorage.setItem("unreadNotification", 0);
}
}
})
.catch(error => {
alert(error);
// console.error(error, "ERRRRRORRR");
});
} else {
AsyncStorage.setItem("unreadNotification", 0);
}
}),
5000
);
return null;
}
return { modalVisible: visible };
}
handleOpenModal = () => {
this.setState({ modalVisible: true });
};
handleCloseModal = () => {
const { handleFail } = this.props;
this.setState({ modalVisible: false }, handleFail);
};
render() {
const { modalVisible } = this.state;
const { theme } = this.props;
return (
<View>
<Modal
animationType={animationType ? animationType : "fade"}
transparent={true}
visible={modalVisible}
onRequestClose={this.handleCloseModal}
>
<View style={themes[theme] ? themes[theme] : themes.transparent}>
<OriginalComponent
handleCloseModal={this.handleCloseModal}
{...this.props}
/>
</View>
</Modal>
</View>
);
}
};
I have not used getDerivedStateFromProps but, according to the docs, it is called on initial component mount and before each render update.
Thus your code is creating a new interval timer on each update without clearing any of the earlier timers, which could be causing a race condition of some sort.
You may want to consider using the simpler alternatives listed in the docs, or at a minimum, insure that you cancel an interval before creating a new one.

How do I hash and un-hash the image in react native

I have created an app which captures images and upload to AWS s3. Currently, those are storing in the gallery. I want to hash/encrypt those images once I captured those and before uploading, I want to un-hash /decrypt those. How can I implement those in react native? I googled it but I did not find any way.
My code is,
import React, {Component} from 'react';
import {Platform, StyleSheet,Alert, Text,TouchableOpacity, View,Picker,Animated,Easing,Image, NetInfo,
Dimensions,Button,ScrollView } from 'react-native';
import ImagePicker from 'react-native-image-picker';
import DeviceInfo from 'react-native-device-info';
import { RNS3 } from 'react-native-aws3';
import Form from './Form';
const SIZE = 40;
const { width } = Dimensions.get('window');
class SecondScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
SelectedClass : '',
SelectedSection : '',
SelectedSubject : '',
serverTime : null,
saveImages : [],
testImage : [],
isConnected :false,
schoolId : 10,
userId :9,
connection_Status : "",
logout:false
}
}
getServerTime() {
fetch('http://worldclockapi.com/api/json/utc/now')
.then((response) => response.json())
.then((responseJson) => {
if (responseJson) {
this.setState({
serverTime: responseJson
})
}
console.log(responseJson);
console.log(responseJson);
})
.catch((error) => {
console.error(error);
});
}
componentDidMount = () => {
NetInfo.isConnected.addEventListener(
'connectionChange',
this._handleConnectivityChange
);
NetInfo.isConnected.fetch().done((isConnected) => {
if(isConnected == true)
{
this.setState({connection_Status : "Online"})
}
else
{
this.setState({connection_Status : "Offline"})
}
});
}
componentWillUnmount = () => {
NetInfo.isConnected.removeEventListener(
'connectionChange',
this._handleConnectivityChange
);
}
_handleConnectivityChange = (isConnected) => {
if(isConnected == true)
{
this.setState({connection_Status : 1})
}
else
{
this.setState({connection_Status : 0})
}
};
//change state of class, sesssion and subject
updateClass = (SelectedClass) => {
this.setState({ SelectedClass: SelectedClass })
}
updateSession = (SelectedSection) => {
this.setState({ SelectedSection: SelectedSection })
}
updateSubject = (SelectedSubject) => {
this.setState({ SelectedSubject: SelectedSubject })
}
takePic = () => {
if(this.state.connection_Status==="Online"){
this.getServerTime();
try{
this.setState({capturedTime:this.state.serverTime.currentFileTime+'_'+time},
() => console.log(this.state.serverTime.currentFileTime)
);
} catch (err) {
var date = new Date();
var time = date.getTime();
this.setState({capturedTime:time});
console.log("localtime")
}
}
const options = {
quality: 1.0,
maxWidth: 75,
maxHeight: 75,
base64: true,
skipProcessing: true
}
ImagePicker.launchCamera(options,(responce)=>{
this.state.testImage.push({ uri: responce.uri });
const file ={
uri : responce.uri,
name :responce.fileName,
method: 'POST',
width : 50,
height : 50,
path : responce.path,
type : responce.type,
notification: {
enabled: true
}
}
this.setState(prevState => {
// get the previous state values for the arrays
let saveImages = prevState.saveImages;
// add the values to the arrays like before
saveImages.push(file);
// return the new state
return {
saveImages
}
});
})
}
_upload=()=>{
if(this.state.connection_Status==="Online"){
const config ={
keyPrefix :'uploads/',
bucket : '***********',
region :'********',
accessKey:'************',
secretKey :'*************',
successActionStatus :201
}
this.state.saveImages.map((image) => {
RNS3.put(image,config)
.then((responce) => {
console.log(image);
});
});
if (this.state.saveImages && this.state.saveImages.length) {
Alert.alert('Successfully, saved');
this.setState({saveImages:''});
this.setState({testImage:''});
} else {
Alert.alert('No images captured');
}
} else {
Alert.alert('Upload failed. User is in offline');
}
}
signout = () => {
this.setState({
logout: true
})
}
render() {
return (
<View>
{this.state.error ? <Text>Error: {this.state.error}</Text> : null}
<View style={styles.Camera}>
<TouchableOpacity onPress={this.takePic.bind(this)}>
<Text>Take Picture</Text>
</TouchableOpacity>
</View>
<View style={styles.Send}>
<TouchableOpacity onPress={() => this._upload()}>
<Text>Send</Text>
</TouchableOpacity>
</View>
</View >
}</View>
);
}
}
const styles = StyleSheet.create({
});
export default SecondScreen;

react native modal not close after setState false

I have set modal visibility to false but it still showing. I cant figure out what causes this issue. this my code at loading.js.
I'm use this component in main what happen when setState false but its just close after close simolator and restart the device
import React,{Component} from 'react';
import PropTypes from 'prop-types'
import {View, Image, Modal, StyleSheet, Text} from "react-native";
export default class Loader extends Component{
render(){
const {animationType,modalVisible}=this.props;
return(
<Modal
animationType={animationType}
transparent={true}
visible={modalVisible}>
<View style={styles.wrapper}>
<View style={styles.loaderContainer}>
<Image
source={require('../img/loading.gif')}
style={styles.loaderImage}/>
</View>
</View>
</Modal>
)
}
}
Loader.propTypes={
animationType:PropTypes.string.isRequired,
modalVisible:PropTypes.bool.isRequired
}
this main class
export default class ForoshRah extends Component {
constructor() {
super();
I18nManager.forceRTL(true);
this.state = {
image: null,
images: null,
loadingVisible:false,
};
this.onValueChange2=this.onValueChange2.bind(this);
this.OnSubmiteData=this.OnSubmiteData.bind(this);
}
onValueChange2(value: string) {
this.setState({
Field: value,
});
}
async OnSubmiteData(){
this.setState({loadingVisible:true})
let token = await AsyncStorage.getItem('token',token);
let response = await
fetch(url,{
method:'POST',
headers:{
'Content-Type':'application/json',
Authorization:'JWT'+" "+token,
}
,body: JSON.stringify({
title,
})
})
let register = await response.json();
this.setState({userID:register.id})
if(response.status===200){
this.UploadImage()
}
}
async UploadImage() {
let token = await AsyncStorage.getItem('token',token);
let response = await fetch(url,{
method:'POST',
headers:{
Authorization:'JWT'+" "+token,
},body: formData
})
let uimage = await response;
console.log('user',this.state.userID);
if(response.status=200){
handleCloseModal = () => {
console.log(this.state.loadingVisible);
this.setState({ loadingVisible: false})
});
};
this.props.navigation.dispatch({ type: 'Navigation/BACK' })
}else {
setTimeout(() => {
this.setState({ loadingVisible: false })
}, 100)
}
setTimeout(() => {
this.setState({ loadingVisible: false })
}, 100)
}
render() {
return (
<KeyboardAwareScrollView >
<View style={{marginBottom:'10%'}}>
<Button block style={{backgroundColor:'#8e25a0'}} onPress={this.OnSubmiteData.bind(this)}>
</Button>
</View>
<Loader
modalVisible={loadingVisible}
animationType="fade"
/>
</KeyboardAwareScrollView>
);
}
}
onsubmitdata setState true and after response going to 200 Setstate set false in code main
You cannot just call state name as you have did. You should do like below.
<Loader
modalVisible={this.state.loadingVisible}
animationType="fade"
/>