Native Base spinner not working - react-native

I am trying to show a spinner on press of button in react-native, native-base after username is entered. It is not working. Here are my steps and code:
Steps:
set loading true in constructor
set loading false after fetching data
if loading true render spinner else load other screen.
constructor(props) {
super(props);
this.state = {
loading: true,
}
handleLoginPressed = async () => {
//some code
let resp = await tryAsk(this.state.sampleQuestion, this.state.username);
this.setState({
loading: false
});
}
render() {
if (this.state.fontsAreLoaded == true) {
if (this.state.isLoggedIn === true) {
if (this.state.loading === true){
<View><Spinner /></View>
}else{
return (
<Somescreen/>
);
}
}

Works fine for me
This is with NativeBase 2.3.6
<Content>
<Spinner />
<Spinner color="red" />
<Spinner color="green" />
<Spinner color="blue" />
</Content>
Works with <View> as well

you forget return
constructor(props) {
super(props);
this.state = {
loading: true,
}
handleLoginPressed = async () => {
//some code
let resp = await tryAsk(this.state.sampleQuestion, this.state.username);
this.setState({
loading: false
});
}
render() {
if (this.state.fontsAreLoaded == true) {
if (this.state.isLoggedIn === true) {
if (this.state.loading === true){
return <Spinner />
}else{
return (
<Somescreen/>
);
}
}

Related

How to add a condition for the user's connection?

I want to add to this code the condition: if the user is connected, he goes directly to BottomTabNavigator (which is the opening of the application) and otherwise he goes in the Authentication file which will allow him to either connect or register. How can I do this ?
Usually I used
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import BottomTabNavigator from "./Navigation/TabNavigator";
const App = () => {
return (
<NavigationContainer>
<BottomTabNavigator />
</NavigationContainer>
);
}
export default App
Usually in a class component I used this, but I don't know how to do with the new syntax:
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
isFirstConnection: true,
status: 0,
fontLoaded: false
};
}
async UNSAFE_componentWillMount() {
let lang = await retrieveAppLang();
let isConnected = await userSessionActive();
if (lang.length == 2) {
i18n.changeLanguage(lang);
}
if (isConnected === true && this.props && this.props.navigation) {
this.props.navigation.navigate("TabBar");
}
}
async componentDidMount() {
await Font.loadAsync({
FunctionLH: require("./assets/fonts/FunctionLH-Light.ttf")
});
const data = await this.performTimeConsumingTask();
if (data !== null) {
this.setState({
isFirstConnection: false,
status: 1,
fontLoaded: true,
});
}
}
performTimeConsumingTask = async () => {
return new Promise((resolve) =>
setTimeout(() => {
resolve("result");
}, 750)
);
};
render() {
if (this.state.status == 1) {
if (this.state.isFirstConnection && this.state.fontLoaded) {
return <SplashScreen />;
} else {
return <Navigation screenProps={'Authentication'} />;
}
}
return (
<ImageBackground
source={require("./assets/images/background.jpg")}
style={{ flex: 1 }}
>
<View style={[styles2.container, styles2.containerCentered]}>
<StatusBar hidden={true} />
<View style={styles2.subContainer}>
<Image
style={styles2.logo}
source={require("./assets/images/logo.png")}
/>
<ActivityIndicator size="large" color="#43300E" />
<Text>{i18n.t("app.loading") + "..."}</Text>
</View>
</View>
</ImageBackground>
);
}
}}
the 'isConnected' is on a file "myPreferences"
export async function userSessionActive() {
let userAuthorizationCode = await retrieveProfileAuthorizationCode();
let userUserId = await retrieveProfileUserId();
let userEmail = await retrieveProfileLogin();
let is_connected = false;
if (userAuthorizationCode != '' && userUserId !== null && parseInt(userUserId) > 0 && userEmail != '') {
is_connected = true;
}
return is_connected;
}
I thought doing something like this but it's not working :
function App(userSessionActive) {
const isConnected = userSessionActive.isConnected;
if (isConnected) {
return <NavigationContainer>
<BottomTabNavigator />
</NavigationContainer>;
}
return <StackNavigator screenProps={'Authentication'}/>;
}
export default App

Trying to add a '[RCTVirtualText 507]' to a '[RCTView 509]')?

I had been developing my app for Web, and it has been working properly. However, when I ran the same app within Expo / Android, I got this error. Hard to know what it is about from the description.
This is the full error message:
Cannot add a child that doesn't have a YogaNode to a parent without a measure function! (Trying to add a '[RCTVirtualText 507]' to a '[RCTView 509]')
Do you know what it could possibly be?
This seems to be the js file that is triggering it:
...
export class SubjectListAssignScreen extends React.Component {
state = {
subjectList: [],
subListLoading: true,
};
constructor(props) {
super(props);
};
scrollDimensions = [{
width: Math.round(Dimensions.get('window').width - 20),
maxHeight: Math.round(Dimensions.get('window').height - 200)
}];
...
_getSubjects = async(text) => {
try {
await this.setState({ subListLoading: true });
let lQueryRes = await API.graphql(graphqlOperation(cqueries.listSubjectsCustom, {}));
await console.log('==> Subjects Query');
await console.log(lQueryRes);
await this.setState({ subjectList: lQueryRes.data.listSubjects.items });
await this.setState({ subListLoading: false });
}
catch (e) {
console.log("==> DB Error");
console.log(e);
await this.setState({ subListLoading: false });
};
};
...
_subjectItems = (value) => {
console.log(value.desc);
let lnum = (typeof value["num"] !== 'undefined') ? value["num"].toString() : null;
let desc = value["desc"].toString();
let lastName = (typeof value["users"][0] !== 'undefined') ? value["users"][0]["lastname"].toString() : null;
let ltype = value["type"].toString();
return (
<DataTable.Row onPress={() => {
this.props.navigation.navigate("UserListScreen", {pnum: lnum, ptype: ltype});
}}>
<DataTable.Cell>
{this._getTypeIcon(ltype)}
</DataTable.Cell>
<DataTable.Cell>
<Text>{desc}</Text>
</DataTable.Cell>
<DataTable.Cell>
<Text>{ lastName }</Text>
</DataTable.Cell>
</DataTable.Row>
);
};
async componentDidMount() {
try {
await this._getSubjects();
}
catch (e) {
console.log("==> componentDidMount error");
console.log(e);
};
};
isCloseToBottom = ({ layoutMeasurement, contentOffset, contentSize }) => {
const paddingToBottom = 20;
return layoutMeasurement.height + contentOffset.y >=
contentSize.height - paddingToBottom;
};
fetchMore = () => {
};
render() {
let sDimensions = this.scrollDimensions;
return (
<View style={{flex:20, margin:4, flexDirection:"column", justifyContent:"flex-start"}}>
<Title style={{flex:1}}>Lista de Demandas</Title>
<SafeAreaView style={[{flex:19, }, sDimensions]}>
<ScrollView
contentContainerStyle={{}}
onScroll={({nativeEvent}) => {
if (this.isCloseToBottom(nativeEvent)) {
this.fetchMore();
}}}
>
<DataTable>
<DataTable.Header>
<DataTable.Title>Type</DataTable.Title>
<DataTable.Title>Subj</DataTable.Title>
<DataTable.Title>Resp.</DataTable.Title>
</DataTable.Header>
{ !this.state.subListLoading ?
<FlatList
data={this.state.subjectList}
renderItem={({item})=>this._subjectItems(item)}
keyExtractor={item => item.desc}
/>
:
<ActivityIndicator />
}
</DataTable>
</ScrollView>
</SafeAreaView>
</View>
)
}
}
Using Expo 37, React Native paper and AWS Amplify.
As I had such a hard time trying to find which components were not compatible, I simply dropped my full development environment, create a clean one and pulled the latest commit again, checking all components version by version and making sure all of them were at the -g version. The error has stopped after that.

Is there any way to display <Text> with a timer setTimeout() multiple times?

I'm trying to return 9 differents Text with a 5 seconds delay between each ones but it's only working for the first Text
i've tried using
render() {
setTimeout(() => {this.setState({timePassed: true})}, 2000);
if(this.state.timePassed == false){
return (
<Text></Text>
)
}else if (this.state.timePassed == true{
return(
<Text>HELLO</Text>
)
}else if (this.state.timePassed1 == false{
............
}
}
but not working
I have also tried
componentDidUpdate(){
setTimeout(() => {this.setState({timePassed1: true})}, 4000);
if(this.state.timePassed1 == true){
return(
<Text>test</Text>)
}
}
but not working
Here is my screen
export default class Internet2 extends React.Component {
constructor(props){
super(props);
this.state = {
timePassed: false,
timePassed1: false
};
}
componentDidUpdate(){
setTimeout(() => {this.setState({timePassed1: true})}, 4000);
if(this.state.timePassed1 == true){
return(
<Text>test</Text>)
}
}
render() {
setTimeout(() => {this.setState({timePassed: true})}, 2000);
if(this.state.timePassed == false){
return (
<Text></Text>
)
}else{
return(
<Text>HELLO</Text>
)
}
}
}
Thank you for your help !
What you can do is keep the texts in an array and a variable for counting how many times has it passed.
state = {
texts = ['sometext', ...]
textCount = 0
}
Then you will create a setInterval to loop in the time you want
componentDidMount() {
let timer = setInterval(() => {
this.setState(prevState => {
return {textCount: prevState.textCount + 1}
})
if (this.state.textCount > this.state.texts.length) clearInterval(timer);
}, theTimeYouWant);
}
And render the texts using .map
render() {
return (
<View>
{this.state.texts.map((text, i) => i <= this.state.textCount ?
<Text>{text}</Text> : null
)}
</View>
)
}
I found the solution, its in render and you have to go like:
constructor(props){
super(props);
this.state = {
timePassed: false,
timePassed1: false
};
}
render() {
setTimeout(() => {this.setState({timePassed: true})}, 2000);
setTimeout(() => {this.setState({timePassed1: true})}, 3000);
return (
<View>
{this.state.timePassed == true ? (<Text>INTERNET</Text>) : null}
{this.state.timePassed1 == true ? (<Text>TEST</Text>) : null}
</View>
)
}
}

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"
/>

React native : Is there any way to redirect the initial route to another page

I'm new in react native and currently developing a react-native app that require login. After successful login, the view change into Homepage. The problem is after i close and re-open the app, it shows me LoginPage again.Is there any way to redirect the initial route to another page
class Main extends Component {
_renderScene(route, navigator) {
if (route.id === 1) {
return <LoginPage navigator={navigator} />
} else if (route.id === 2) {
return <HomePage navigator={navigator} />
} else if (route.id === 3) {
return <DetailPage navigator={navigator} />
} else if (route.id === 4) {
return <CreateBookingPage navigator={navigator} />
}
}
_configureScene(route) {
return Navigator.SceneConfigs.PushFromRight;
}
render() {
return (
<Navigator
initialRoute={{id: 1, }}
renderScene={this._renderScene}
configureScene={ () => { return Navigator.SceneConfigs.PushFromRight; }} />
);
}
}
/////after some changes I get into this but still its rendering the login is I done something wrong////////
componentWillMount() {
AsyncStorage.getItem('key').then( (value) => {
if(value==="yes") {
this.setState({ loader: false, logged: true})
} else {
this.setState({ loader: false })
}
})
}
render() {
const routeId = this.state.logged ? 2 : 1;
if(this.state.loader) {
return (
<View /> // loading screen
);
}
return (
<Navigator
initialRoute={{id: routeId }}
renderScene={this._renderScene}
configureScene={ () => { return Navigator.SceneConfigs.PushFromRight; }} />
);
}
On successful login you could set a token/value in the local storage of the device and on logout clear this value.
You could check this value for setting the initial route. Asyncstorage can be used in setting and removing the logged status.
EDIT:
Initial state of loader should be true, logged should be false
componentWillMount() {
AsyncStorage.getItem('key').then( (value) => {
if(value) {
this.setState({ loader: false, logged: true})
} else {
this.setState({ loader: false })
}
})
}
render() {
const { loader } = this.state;
const routeId = logged ? 2 : 1;
if(loader) {
return (
<View /> // loading screen
);
}
return (
<Navigator
initialRoute={{id: routeId }}
renderScene={this._renderScene}
configureScene={ () => { return Navigator.SceneConfigs.PushFromRight; }} />
);
}
Replace with your render function and try it.
render() {
var loggedStatus = true; // change here for login screen
var routeId = loggedStatus ? 2 : 1;
return (
<Navigator
initialRoute={{id: routeId }}
renderScene={this._renderScene}
configureScene={ () => { return Navigator.SceneConfigs.PushFromRight; }} />
);
}