Cannot access the state but i see it on debbugger - reactjs

I have function to fetch my data, and i do setState to put my data inside my state.
But i dont understand how to use it in my render()
getFixture = async () => {
const url = 'http://127.0.0.1:80/testmatch/get_fixture.php';
fetch(url).then((reponse) => reponse.json())
.then((reponseJson) => {
this.setState({
data:reponseJson,
isLoading:false
})
})
}
componentDidMount(){
this.getFixture()
}
if i do a console.log(this.state.data); in my render is show me this in the console (in image join)
if i do console.log(this.state.data.elapsed); is working and i get the value but if i do console.log(this.state.data.awayTeam.logo); i get Cannot read property 'logo'
I dont understand why.
Screenshot
Here is all the code, that i want is to use all datas from my data State to my render :
getFixture = async () => {
const url = 'http://127.0.0.1:80/testmatch/get_fixture.php';
fetch(url).then((reponse) => reponse.json())
.then((reponseJson) => {
this.setState({
data:reponseJson,
isLoading:false
})
console.log(this.state.data.awayTeam.logo); // WORKING (SHOW ME THE LINK)
})
}
render() {
console.log(this.state.data.awayTeam.logo); // NOT WORKING (CANNOT READ PROPERTY OF UNDEFINED)
return (
<View style={styles.container}>
<View style={styles.containerScore}>
<View style={{flex: 1, flexDirection: 'row', borderColor:'#171F33',borderBottomWidth: 1 }}>
<View style={{flex: 1,paddingTop:7,paddingBottom:7}}>
<View style={{flex: 1}}>
<Image style={{width: 50, height: 50}} source={{uri: "toto"}} />
</View>
</View>
<View style={{flex: 1,paddingTop:7,paddingBottom:7, backgroundColor:'#fff'}}>
<Text style={{fontSize:13}}> {this.state.data.elapsed}</Text>
</View>
<View style={{flex: 1,paddingTop:7,paddingBottom:7, marginLeft:2, backgroundColor:'#000'}}>
<Text style={{fontSize:13}}></Text>
</View>
</View>
<Text style={{color:"#FFF"}}>{} </Text>
</View>
<View style={styles.containerInfo}>
<ScrollableTabView style={{marginTop: 1}} initialPage={0} renderTabBar={() => <CustomTabBar/>} >
<View tabLabel='Tab #1'>
<Text>My</Text>
</View>
<View tabLabel='Tab #2'>
<Text>favorite</Text>
</View>
<View tabLabel='Tab #3'>
<Text>favorite</Text>
</View>
<View tabLabel='Tab #4'>
<Text>favorite</Text>
</View>
</ScrollableTabView>
</View>
</View>
);
}
}

In the initial render, the this.state.data is not yet set, so if you try to access it without null checking it will give you an error.
In your jsx, you can check if this.state.data is falsy and if it is falsy return immediately like this:
render() {
if (!this.state.data) {
return (<View><Text>Loading...</Text></View>);
}
console.log(this.state.data.awayTeam.logo);
return (
<View style={styles.container}>
<View style={styles.containerScore}>
<View style={{flex: 1, flexDirection: 'row', borderColor:'#171F33',borderBottomWidth: 1 }}>
<View style={{flex: 1,paddingTop:7,paddingBottom:7}}>
<View style={{flex: 1}}>
<Image style={{width: 50, height: 50}} source={{uri: "toto"}} />
</View>
</View>
<View style={{flex: 1,paddingTop:7,paddingBottom:7, backgroundColor:'#fff'}}>
<Text style={{fontSize:13}}> {this.state.data.elapsed}</Text>
</View>
<View style={{flex: 1,paddingTop:7,paddingBottom:7, marginLeft:2, backgroundColor:'#000'}}>
<Text style={{fontSize:13}}></Text>
</View>
</View>
<Text style={{color:"#FFF"}}>{} </Text>
</View>
<View style={styles.containerInfo}>
<ScrollableTabView style={{marginTop: 1}} initialPage={0} renderTabBar={() => <CustomTabBar/>} >
<View tabLabel='Tab #1'>
<Text>My</Text>
</View>
<View tabLabel='Tab #2'>
<Text>favorite</Text>
</View>
<View tabLabel='Tab #3'>
<Text>favorite</Text>
</View>
<View tabLabel='Tab #4'>
<Text>favorite</Text>
</View>
</ScrollableTabView>
</View>
</View>
)
}
A simple demo in codesandbox

Try to log in the setState callback like this
this.setState({
data:reponseJson,
isLoading:false
}, () => {
console.log(this.state.data.awayTeam.logo)
})

Related

React Native - ScrollView not scrolling

I'm currently making a registration form using React Native. When I implement into the application, a scroll bar doesn't work.
return (
<TouchableWithoutFeedback
onPress={() => {
Keyboard.dismiss();
}}>
<View style={styles.container}>
<ScrollView>
<View style={styles.formContainer}>
<View style={styles.registerTextContainer}>
{/* <Text style={styles.registerText}>Register for an account</Text> */}
</View>
<Form type={User} ref={c => (this._form = c)} options={options} />
<TouchableOpacity
style={styles.registerButtonContainer}
onPress={this.handleSubmit}>
<Text style={styles.registerButtonText}>REGISTER</Text>
</TouchableOpacity>
</View>
</ScrollView>
</View>
</TouchableWithoutFeedback>
);
}
This is how the application currently looks
Trying wrapping the whole page with ScrollView instead of TouchableWithoutFeedback and set flex to 1
return (
<ScrollView style={{ flex: 1 }}>
<TouchableWithoutFeedback
onPress={() => {
Keyboard.dismiss();
}}
>
<View style={styles.container}>
<View style={styles.formContainer}>
<View style={styles.registerTextContainer}>
{/* <Text style={styles.registerText}>Register for an account</Text> */}
</View>
<Form type={User} ref={(c) => (this._form = c)} options={options} />
<TouchableOpacity
style={styles.registerButtonContainer}
onPress={this.handleSubmit}
>
<Text style={styles.registerButtonText}>REGISTER</Text>
</TouchableOpacity>
</View>
</View>
</TouchableWithoutFeedback>
</ScrollView>
);
Don't set flex:1 in scroll view, instead try
<ScrollView contentContainerStyle={{ flexGrow: 1}}>

changing the styling of one text element from inside another text element

so basically, am trying to achieve something like so, such that when +100 is pressed, the color of say, Upload ID Card changes to really show that that field is completed.
<View
style={{ justifyContent: "flex-start", marginTop: 25 }}
>
<Text
style={ styles.scoreTitle }
>
{item.key}
</Text>
</View>
<View style={styles.perScoreRightContentView}>
<Text
style={styles.scorePlus100}
onPress={() => // change style of the the text child above}
>
+ 100
</Text>
<MaterialIcons name="keyboard-arrow-right" size={24} />
</View>
</View>
So, this is what I have tried out but with no success;
...
const [isSelected, setIsSelected] = React.useState(false);
...
<Text
style={[
isSelected
? { ...styles.scoreTitle, color: "#C6C6C6" }
: styles.scoreTitle
]}
>
{item.key}
</Text>
</View>
<TouchableOpacity
style={styles.perScoreRightContentView}
onPress={() => setIsSelected(!isSelected)}
>
<Text style={styles.scorePlus100}>+ 100</Text>
<MaterialIcons name="keyboard-arrow-right" size={24} />
</TouchableOpacity>
...
const styles = StyleSheet.create({
scoreTitle: {
color: style.color.blackText,
fontSize: 13,
fontFamily: style.fontFamily.medium
}
});
Now I understand, you can put a ref on the text element and access to syle of that text element from the press function.
some thing like that :
<View style={{ justifyContent: "flex-start", marginTop: 25 }}>
<Text style={ styles.scoreTitle } ref='colorText'>
{item.key}
</Text>
</View>
<View style={styles.perScoreRightContentView}>
<Text style={styles.scorePlus100} onPress={() => changeStyle()}>
+ 100
</Text>
<MaterialIcons name="keyboard-arrow-right" size={24} />
</View>
const changeStyle = () => {
const myReference = this.colorText.current // The DOM element
myReference.style.color = "yellow";
}
don't forget to useRef to declar the ref.
I actually found a solution, thanks rovas
So basically what had to be done was to split components such that they manage different state, that is to say,
const Score = ({ title }: { title: string }) => {
const [scoreSelected, setScoreSelected] = React.useState(false);
return (
<View style={styles.perSectionScore}>
<View style={{ justifyContent: "flex-start", marginTop: 25 }}>
<Text
style={[
scoreSelected
? { ...styles.scoreTitle, color: "#C6C6C6" }
: styles.scoreTitle
]}
>
{title}
</Text>
</View>
<View
style={styles.perScoreRightContentView}
>
<Text
style={styles.scorePlus100}
onPress={() => {
setScoreSelected(!scoreSelected);
}}
>
+ 100
</Text>
<MaterialIcons name="keyboard-arrow-right" size={24} />
</View>
</View>
);
};
and then use in a to-be rendered component, i.e
<View style={styles.scoresContainer}>
<FlatList
data={scoreTitles}
renderItem={({ item }) => {
const index = scoreTitles.indexOf(item);
return (
<>
{
<View
key={index}
style={{
padding: 10
}}
>
<Score title={item.key}/>
<View style={{ flex: 0.5 }}>
<Input
disabled={true}
inputContainerStyle={{ borderBottomColor: "#EAEAEA" }}
/>
</View>
</View>
}
</>
);
}}
/>
</View>
</View>
);
...

How to show ActivityIndictor when data is fetched in react native

I have a react native app with PHP backEnd (SQL server DB)
Well ,As you see in pictures ,I have a form where user can enter month and year and search DB's information ;
My code do:
1/ if a variable is setting true => I will get just my form
2/ if I click on button => variable became false and show the form and data ;
My problem is when I click on button ,it takes some time to show results so in this case I wan add an ActivityIndicator as a sign that something is working behind ;
This is my code :
export default class FirstPage extends React.Component {
constructor(props){
super(props);
this.state ={
isLoading: true,
dataSource: [],
month:'',
year:'',
}
}
afficher = () =>{
this.setState({
Loading: false})
const month = this.state.month;
const year= this.state.year;
return fetch('http://192.168.1.2:80/netOne/fetch.php',{
method:'post',
header:{
'Accept':'application/json',
'Content-type' :'application/json'
},
body:JSON.stringify({mois:month,annee:year})})
.then((response) => response.json())
.then((responseJson) => {
if(responseJson=="null"){
}
else {this.setState({
isLoading: false,
dataSource: responseJson,});}}
)
.catch((error) =>{console.error(error);});
this.setState({
month:'',
year:'',})
}
render() {
if(this.state.isLoading){
return(
<View style={{flex: 1}}>
<View style={{alignItems: 'center' }}>
<View style={{marginTop:30,width:Dimensions.get("window").width*0.8,backgroundColor:'#ffffff',height:150}}>
<Text style={{marginTop:20,marginLeft:20,color:'grey'}}> Month :</Text>
<TextInput placeholder="Enter value" style={{marginLeft:20,paddingLeft:5,marginRight:20,borderBottomColor: '#f2f2f2',borderBottomWidth: 1,}} onChangeText= {month=>this.setState({month})}/>
<Text style={{marginTop:20,marginLeft:20,color:'grey'}}> Year :</Text>
<TextInput placeholder="Enter value" style={{marginLeft:20,marginRight:20,paddingLeft:5,borderBottomColor: '#f2f2f2',borderBottomWidth: 1,}} onChangeText= {year=>this.setState({year})}/>
</View>
<TouchableOpacity style={{borderRadius:12,width:Dimensions.get("window").width*0.8,backgroundColor:'#ff9900',height:50,marginTop:10}} onPress={this.afficher}>
<Text style={{marginTop:15,color:'white',textAlign:'center',fontSize:14}}>Afficher</Text>
</TouchableOpacity>
</View>
</View>
)}
return (
<ScrollView style={{ flex: 1,backgroundColor:'#f2f2f2'}}>
<View style={{alignItems: 'center' }}>
<View style={{marginTop:30,width:Dimensions.get("window").width*0.8,backgroundColor:'#ffffff',height:150}}>
<Text style={{marginTop:20,marginLeft:20,color:'grey'}}> Month :</Text>
<TextInput placeholder="Enter value" style={{marginLeft:20,paddingLeft:5,marginRight:20,borderBottomColor: '#f2f2f2',borderBottomWidth: 1,}} onChangeText= {month=>this.setState({month})}/>
<Text style={{marginTop:20,marginLeft:20,color:'grey'}}> Year :</Text>
<TextInput placeholder="Enter value" style={{marginLeft:20,marginRight:20,paddingLeft:5,borderBottomColor: '#f2f2f2',borderBottomWidth: 1,}} onChangeText= {year=>this.setState({year})}/>
</View>
<TouchableOpacity style={{borderRadius:12,width:Dimensions.get("window").width*0.8,backgroundColor:'#ff9900',height:50,marginTop:10}} onPress={this.afficher}>
<Text style={{marginTop:15,color:'white',textAlign:'center',fontSize:14}}>Afficher</Text>
</TouchableOpacity>
</View>
<View style={{ paddingLeft:10 ,paddingTop:10 ,paddingBottom:10}}>
<View style={{ flexDirection:'row' }}>
<Text style={styles.head}> Client </Text>
<Text style={styles.head1}>Mois</Text>
<Text style={styles.head2}>Annee</Text>
<Text style={styles.head3}>ChiffreAffaire</Text>
</View>
<FlatList
data={this.state.dataSource}
renderItem={({item}) =><Item title={item.M500_NOM} title1={item.Mois} title2={item.Annee} title3={item.ChiffreAffaire}/>}
ListEmptyComponent={this._listEmptyComponent}
keyExtractor={(item, index) => index.toString()}
/>
</View>
</ScrollView>
);
}
}
Here is an updated version of your code.
return (
<ScrollView style={{ flex: 1,backgroundColor:'#f2f2f2'}}>
<View style={{alignItems: 'center' }}>
<View style={{marginTop:30,width:Dimensions.get("window").width*0.8,backgroundColor:'#ffffff',height:150}}>
<Text style={{marginTop:20,marginLeft:20,color:'grey'}}> Month :</Text>
<TextInput placeholder="Enter value" style={{marginLeft:20,paddingLeft:5,marginRight:20,borderBottomColor: '#f2f2f2',borderBottomWidth: 1,}} onChangeText= {month=>this.setState({month})}/>
<Text style={{marginTop:20,marginLeft:20,color:'grey'}}> Year :</Text>
<TextInput placeholder="Enter value" style={{marginLeft:20,marginRight:20,paddingLeft:5,borderBottomColor: '#f2f2f2',borderBottomWidth: 1,}} onChangeText= {year=>this.setState({year})}/>
</View>
<TouchableOpacity style={{borderRadius:12,width:Dimensions.get("window").width*0.8,backgroundColor:'#ff9900',height:50,marginTop:10}} onPress={this.afficher}>
<Text style={{marginTop:15,color:'white',textAlign:'center',fontSize:14}}>Afficher</Text>
</TouchableOpacity>
{(this.state.dataSource.length != 0) </View>
<View style={{ paddingLeft:10 ,paddingTop:10 ,paddingBottom:10}}>
<View style={{ flexDirection:'row' }}>
<Text style={styles.head}> Client </Text>
<Text style={styles.head1}>Mois</Text>
<Text style={styles.head2}>Annee</Text>
<Text style={styles.head3}>ChiffreAffaire</Text>
</View>
<FlatList
data={this.state.dataSource}
renderItem={({item}) =><Item title={item.M500_NOM} title1={item.Mois} title2={item.Annee} title3={item.ChiffreAffaire}/>}
ListEmptyComponent={this._listEmptyComponent}
keyExtractor={(item, index) => index.toString()}
/>
</View>}
{this.state.loading &&
<ActivityIndicator/>
}
</ScrollView>
);

react-native's borderRadius makes backgroundColor transparent

This is normal Screen :
This is abnormal Screen :
The property borderRadius affect backgroundColor , I really don't know what the problem is.
Please help me solve this problem.
This is my components Panel.js
const styles = StyleSheet.create({
container:{
flex:1,
backgroundColor:'#ffffff',
margin:$F.scale(10),
// borderRadius:$F.scale(3),
paddingLeft:$F.scale(8),
paddingRight:$F.scale(8),
},
contTitle:{
flexDirection:'row',
paddingTop:$F.scale(10),
paddingBottom:$F.scale(10),
marginBottom:$F.scale(10),
alignItems:'center',
borderBottomWidth:$F.compatiblePixel*1,
borderBottomColor:'#DFDFDF',
},
cont:{
flex:1,
paddingBottom:$F.scale(10),
},
rightHeader:{
flex:1,
flexDirection:"row",
justifyContent:'flex-end',
// backgroundColor:"#444444",
}
});
<View style={styles.container}>
<View style={styles.contTitle}>
<Text style={{fontSize:$F.scale(13),color:"#000000",flex:1}}>{this.state.titleCont}</Text>
<SelectOption
options={this.state.selOptions}
onSelectOptions={this._ChooseList.bind(this)}
selectShow={this.props.rightHeader?false:this.props.selectShow}
/>
<View style={[{display:this.props.rightHeader?"flex":"none"},styles.rightHeader]}>
{
this.props.rightHeader
}
</View>
</View>
<View style={styles.cont} >
{this.props.children}
</View>
</View>
I use in learnning.js
<ScrollView style={[this.props.style,styles.container]}>
<Panel titleCont="学习轨迹" selectShow={false}>
<View style={styles.progressItems}>
<View style={styles.Line}></View>
<View style={styles.progressBox}>
{this.state.learningData.map((v,i)=>{
return (
<ProcessBox key={v.id}>
<TouchableHighlight underlayColor="rgba(0,0,0,0)" activeOpacity={1} onPress={()=>{this._getClassifyId(v.secondClassifyId,v.id)}}>
<View style={styles.learnLesson}>
<View style={styles.lessonImg} >
<Image source={{uri:IMGHEADURL+v.cover}} style={styles.Image}/>
</View>
<View style={styles.lessonMsg}>
<Text style={{fontSize:$F.scale(7.7),color:"#4A4A4A"}}>{v.name}</Text>
<Text style={{fontSize:$F.scale(6),color:"#BBBBBB",marginBottom:$F.scale(5.5)}}>{formatTime(v.hasStudy?v.study_time:v.create_time,"full")}</Text>
<View style={styles.lessonStatus}>
<View style={[styles.statusItems,styles.status1]}>
<Text style={{fontSize:$F.scale(6.1),color:"#E5E0D0"}}>{v.hasStudy?"练习中":"未练习"}</Text>
</View>
<View style={[styles.statusItems,styles.status2]}>
<Text style={{fontSize:$F.scale(6.1)}}>{v.firstClassifyName}</Text>
</View>
<View style={[styles.statusItems,styles.status2]}>
<Text style={{fontSize:$F.scale(6.1)}}>{v.secondClassifyName}</Text>
</View>
<View style={styles.shareBtn}>
<ICON name="uniE917" size={$F.scale(8.8)} color="#C8C8C8" />
</View>
</View>
</View>
</View>
</TouchableHighlight>
</ProcessBox>
)
})}
</View>
</View>
</Panel>
</ScrollView>
The number of cycles is within ten, the style is good, and more than ten the backgroundColor is transeparents.

React native scroll view no scrolling

I have the following code which is returned in a render function in my react-native app. container have its flex property set to 1.
Even when the content is overflowing the scroll is not working. What am I doing wrong?
Also tried setting flex for ScrollView to 1. Still not working.
<View style={globalStyle.container}>
{flashMessage}
<ScrollView>
<View style={globalStyle.header}>
<Text style={globalStyle.title}> {localization.categories} </Text>
</View>
<ListView style={{marginTop: 10}}
dataSource={this.state.dataSource}
renderRow={(rowData, sectionID, rowID)=> this.renderRow(rowData, sectionID, rowID)}
/>
</ScrollView>
<View style={{position: 'absolute', height: 70, left: 0, right: 0, bottom: 0, flexDirection:'row', justifyContent:'center'}}>
<TouchableHighlight style={globalStyle.footer} onPress={() => { this.redirect('home'); }} >
<View>
<Image style={globalStyle.footerIcons} source={require('./Thumbnails/ -button-selected.png')}/>
<Text style={globalStyle.footerText,globalStyle.selected} > {localization.meditate} </Text>
</View>
</TouchableHighlight>
<TouchableHighlight style={globalStyle.footer} onPress={() => { this.redirect('profile');}} >
<View>
<Image style={globalStyle.footerIcons} source={require('./Thumbnails/user.png')} />
<Text style={globalStyle.footerText} > {localization.me} </Text>
</View>
</TouchableHighlight>
<TouchableHighlight style={globalStyle.footer} onPress={() => { this.redirect('settings');}}>
<View>
<Image style={globalStyle.footerIcons} source={require('./Thumbnails/settings.png')} />
<Text style={globalStyle.footerText} > {localization.settings} </Text>
</View>
</TouchableHighlight>
</View>
</View>
I believe you shouldn't use ListView inside ScrollView.
You can use renderHeader function and put there
your header:
<View style={globalStyle.header}>
<Text style={globalStyle.title}> {localization.categories} </Text>
</View>

Resources