I am trying to hide/show a button in header of a React Native Toolbar. I would like the buttons to show once the user logs in. I get the error undefined is not an object on this.state.status. How can I get the state in the toolbar?
export default class TestSC extends React.Component {
constructor(){
super();
this.state ={
status:false
}
}
static navigationOptions = ({navigation})=> {
return {
title: 'Tin Tin Foil',
headerRight: (
<View style={styles.twoButtonView}>
{(this.state.status == true) ?
<TouchableOpacity onPress={this._refreshButtonPress}>
<Image source={require('../img/ic_search_white.png')} style={styles.refrgeshButton} />
</TouchableOpacity>
: null}
<Button
onPress={() => navigation.navigate('Login')}
title="Login" color="#fff" />
</View>
),
}};
toggleStatus(){
this.setState({
status:!this.state.status
});
console.log('toggleStatus: '+ this.state.status);
}
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Test</Text>
<TouchableHighlight onPress={()=>this.toggleStatus()}>
<Text> Click Me Toggle </Text>
</TouchableHighlight>
</View>
);
}
}
You can use navigation params to achieve this.
While setting component state, you need to set Navigator params as well.
this.props.navigation.setParams({
status: true
})
And use navigator params in the header.
navigation.state.params.status == true
Complete Example
export default class TestSC extends React.Component {
constructor() {
super();
this.state = {
status: false
}
}
static navigationOptions = ({navigation, screenProps}) => {
if (!navigation.state.params) {
navigation.state.params = {}
}
return {
title: 'Tin Tin Foil',
headerRight: (
<View style={styles.twoButtonView}>
{(navigation.state.params.status == true) ?
<TouchableOpacity onPress={this._refreshButtonPress}>
<Text>Login</Text>
</TouchableOpacity>
: null}
</View>
),
}
};
toggleStatus() {
this.setState(pre => {
pre.status = !pre.status
this.props.navigation.setParams({
status: pre.status
})
return pre
})
console.log('toggleStatus: ' + this.state.status);
}
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Test</Text>
<TouchableHighlight onPress={()=>this.toggleStatus()}>
<Text> Click Me Toggle </Text>
</TouchableHighlight>
</View>
);
}
}
Related
I'm new to React native and development in general and am trying to retrieve data from an webservice and then render it but I seem to be running into different errors.
I am getting this error
import React, { Component } from "react";
import {StyleSheet,View,ActivityIndicator,FlatList,Text,TouchableOpacity} from "react-native";
export default class Source extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: "Source Listing",
headerStyle: {backgroundColor: "#fff"},
headerTitleStyle: {textAlign: "center",flex: 1}
};
};
constructor(props) {
super(props);
this.state = {
loading: false,
items:[]
};
this.fetchRequest=this.fetchRequest.bind.this
}
FlatListItemSeparator = () => {
return (
<View style={{
height: .5,
width:"100%",
backgroundColor:"rgba(0,0,0,0.5)",
}}
/>
);
}
componentDidMount()
{
fetchRequest();
}
renderItem=(data)=>
<TouchableOpacity style={styles.list}>
<Text style={styles.lightText}>{data.item.name}</Text>
<Text style={styles.lightText}>{data.item.email}</Text>
<Text style={styles.lightText}>{data.item.company.name}</Text>
</TouchableOpacity>
render(){
fetchRequest()
{
const parseString = require('react-native-xml2js').parseString;
fetch('http://192.168.200.133/apptak_service/apptak.asmx/Get_Item_Master')
.then(response => response.text())
.then((response) => {
parseString(response, function (err, result) {
console.log(response)
});
}).catch((err) => {
console.log('fetch', err)
this.fetchdata();
})
if(this.state.loading){
return(
<View style={styles.loader}>
<ActivityIndicator size="large" color="#0c9"/>
</View>
)}}
return(
<View style={styles.container}>
<FlatList
data= {this.state.dataSource}
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem= {item=> this.renderItem(item)}
keyExtractor= {item=>item.id.toString()}
/>
</View>
)}
}
<FlatList
data={this.state.items}
renderItem={({ item }) => <Item title={item.title} />}
keyExtractor= {item=>item.id.toString()}
/>
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff"
},
loader:{
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#fff"
},
list:{
paddingVertical: 4,
margin: 5,
backgroundColor: "#fff"
}
});
The main cause what i am trying to achieve is render the 'items' that are returned from the webservice.
Kindly guide me with this error
I recently joined to React Native project team. Due to time constraint, there is no time to learn JavaScript in depth thats why I directly continued the project. My question is how to change fragment by click to the checkbox. So that, when I click to checkbox it changes to another fragment and when I click to uncheck checkbox it goes back to the previous fragment. I found this React Native - CheckBox unable to uncheck the "checked" box
but it was a little bit harder for me to understand.
Here what I did:
export default class App extends React.Component {
constructor(props) {
super(props);
//state to manage the screen visible at a time
this.state = { val: 1 };
}
renderElement() {
//You can add N number of Views here in if-else condition
if (this.state.val === 1) {
//Return the FirstScreen as a child to set in Parent View
return <FirstScreen />;
} else if (this.state.val === 2) {
//Return the SecondScreen as a child to set in Parent View
return <SecondScreen />;
} else {
//Return the ThirdScreen as a child to set in Parent View
return <ThirdScreen />;
}
}
...
<TouchableOpacity
style={styles.button}
onPress={() => this.setState({ val: 1 })}>
<Text style={{ color: '#ffffff' }}>1st View</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => this.setState({ val: 2 })}>
<Text style={{ color: '#ffffff' }}>2nd View</Text>
</TouchableOpacity>
<CheckBox
value = { this.state.check }
onChange={() => this.setState({ val: 2 })/>
//This is where my fragment changes
<View style={{ backgroundColor: '#ffffff' }}>
{this.renderElement()}
</View>
Currently, I am able to go to 2nd fragment. But I can't go back to the first fragment and uncheck the checkbox.
export default class App extends React.Component {
constructor(props) {
super(props);
//state to manage the screen visible at a time
this.state = { val: 1, checked: false };
}
//Toggle state on checkbox change
toggleFragment() {
if(this.state.val == 1) {
this.setState({ val: 2, checked: !this.state.checked });
} else {
this.setState({ val: 1, checked: !this.state.checked});
}
}
renderElement() {
//You can add N number of Views here in if-else condition
if (this.state.val === 1) {
//Return the FirstScreen as a child to set in Parent View
return <FirstScreen />;
} else if (this.state.val === 2) {
//Return the SecondScreen as a child to set in Parent View
return <SecondScreen />;
} else {
//Return the ThirdScreen as a child to set in Parent View
return <ThirdScreen />;
}
}
...
<TouchableOpacity
style={styles.button}
onPress={() => this.setState({ val: 1 })}>
<Text style={{ color: '#ffffff' }}>1st View</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => this.setState({ val: 2 })}>
<Text style={{ color: '#ffffff' }}>2nd View</Text>
</TouchableOpacity>
<CheckBox
value = 'checked'
checked={this.state.checked == true}
onChange={() => this.toggleFragment()/>
//This is where my fragment changes
<View style={{ backgroundColor: '#ffffff' }}>
{this.renderElement()}
</View>
export default class App extends React.Component {
constructor(props) {
super(props);
//state to manage the screen visible at a time
this.state = { check: true };
}
renderElement() {
if (this.state.check) {
return <FirstScreen />;
} else {
return <SecondScreen />;
}
}
...
<TouchableOpacity
style={styles.button}
onPress={() => this.setState({ val: 1 })}>
<Text style={{ color: '#ffffff' }}>1st View</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.button}
onPress={() => this.setState({ val: 2 })}>
<Text style={{ color: '#ffffff' }}>2nd View</Text>
</TouchableOpacity>
<CheckBox
value = { this.state.check }
onValueChange={(newValue) => this.setState({check:newValue})/>
//This is where my fragment changes
<View style={{ backgroundColor: '#ffffff' }}>
{this.renderElement()}
</View>
Thank you Raju and Waheed Akhter. By combining your answers I found a solution. Here is a solution:
constructor(props) {
super(props);
//state to manage the screen visible at a time
this.state = { val: 1, checked: true };
}
//Toggle state on checkbox change
toggleFragment() {
if(this.state.val == 1) {
this.setState({ val: 2});
} else {
this.setState({ val: 1});
}
}
.....
<CheckBox
value = { this.state.check }
onChange={() => this.toggleFragment()}
onValueChange={(newValue) => this.setState({check:newValue})}/>
When I tried alert("Hi") in renderMoreView function, it actually works, but to display the View is the problem I am facing
export default class Home extends Component {
state = {
moreButton: false,
};
renderMoreView = () => {
return (
<View style={{flex: 1, height: 50, width: 50}}>
<Text>Hi</Text>
</View>
);
};
render () {
return (
<View>
.....
<TouchableOpacity
underlayColor="transparent"
onPress={() => this.setState ({moreButton: true})}
>
<Feather name="more-vertical" size={25} />
</TouchableOpacity>
...
{this.state.moreButton ? this.renderMoreView () : null}
</View>
);
}
}
This is what I am trying to do]
If I understand your question right, you could use Modal component. https://facebook.github.io/react-native/docs/modal
This can be done using modal. But if you want to do it more simply, install and use the module. react-native-awesome-alerts
$ npm i react-native-awesome-alerts --save
Example
import React from 'react';
import { StyleSheet, View, Text, TouchableOpacity } from 'react-native';
import AwesomeAlert from 'react-native-awesome-alerts';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { showAlert: false };
};
showAlert = () => {
this.setState({
showAlert: true
});
};
hideAlert = () => {
this.setState({
showAlert: false
});
};
render() {
const {showAlert} = this.state;
return (
<View style={styles.container}>
<Text>I'm AwesomeAlert</Text>
<TouchableOpacity onPress={() => {
this.showAlert();
}}>
<View style={styles.button}>
<Text style={styles.text}>Try me!</Text>
</View>
</TouchableOpacity>
<AwesomeAlert
show={showAlert}
showProgress={false}
title="AwesomeAlert"
message="I have a message for you!"
closeOnTouchOutside={true}
closeOnHardwareBackPress={false}
showCancelButton={true}
showConfirmButton={true}
cancelText="No, cancel"
confirmText="Yes, delete it"
confirmButtonColor="#DD6B55"
onCancelPressed={() => {
this.hideAlert();
}}
onConfirmPressed={() => {
this.hideAlert();
}}
/>
</View>
);
};
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#fff',
},
button: {
margin: 10,
paddingHorizontal: 10,
paddingVertical: 7,
borderRadius: 5,
backgroundColor: "#AEDEF4",
},
text: {
color: '#fff',
fontSize: 15
}
});
I need your help I'm using firebase for my app. I'm trying to get the users ID not the logged users no all users I have. I want to show their (uid) simply like in an alert for each user. Also, I'm showing them in a flatlist and when I set item.uid in an alert it shows (undefined). But, all the other data of the user is shown correctly. This what I did until now:
**
users.js
**
export default class usersList extends React.Component{
state = {
loading: false,
uid: '',
users: [],
items: []
};
componentDidMount() {
let itemsRef = f.database().ref('users').once('value').then(snapshot => {
var data = snapshot.val();
var items = Object.values(data);
this.setState({items});
console.log(snapshot.val())
});
}
renderItem({item}) {
return (
<View key={index} style={{width: '100%', overflow:'hidden', marginBottom: 5, justifyContent:'space-between', borderBottomWidth:1, borderColor: 'grey'}}>
<View>
<View style={{padding:5, width:'100%', flexDirection: 'row', justifyContent: 'space-between'}}>
<Text>{item.email}</Text>
</View>
</View>
</View>
)
}
render() {
return (
<View style={styles.container}>
<ScrollView>
{
this.state.items.length > 0
? <ItemComponent items={this.state.items} navigation={this.props.navigation} />
: <Text>No stores</Text>
}
</ScrollView>
</View>
);
}
}
//ItemComponent.js
export default class ItemComponent extends Component {
static propTypes = {
items: PropTypes.array.isRequired
};
render() {
return (
<View style={styles.itemsList}>
{this.props.items.map((item, index) => {
return (
<View key={index}>
<TouchableOpacity
onPress={ () => alert(item.uid)}>
<Text style={styles.itemtext}>{item.email}</Text>
</TouchableOpacity>
</View>
)
})}
</View>
);
}
}
firebase.database().ref('user').on('value', (datasnapshot) => {
this.setState({
_id: datasnapshot.key
});`
This solution worked for me
<Text style={styles.yourStyleHere}>UID: {auth.currentUser?.uid} </Text>
I have a Drawer Navigator which have screens.
Now I want to access the one screen function in menu button of drawer.
Let suppose
Drawer Navigator:
const Drawer = createDrawerNavigator(
{
Main: {
path: "/Main",
screen: MainScreen
},
LikeScreen: {
path: "/Like",
screen: LikeScreen
},
DislikeScreen: {
path: "/Dislike",
screen: DislikeScreen
}
},
{
initialRouteName: "Main",
drawerWidth: widthPercentageToDP("60%"),
contentComponent: SideMenu,
headerMode: "screen"
}
);
MainScreen:
export default class MainScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
TurnMeOnMainFilterModal: false
};
}
_OpenFilterModel=()=> this.setState({ TurnMeOnMainFilterModal: true });
_closeFilterModel=()=> this.setState({ TurnMeOnMainFilterModal: false });
render() {
return <View>
<Modal
animationType="slide"
transparent={true}
visible={this.state.TurnMeOnMainFilterModal}
presentationStyle="overFullScreen"
>
<View style={Style1.ModalViewContainer}>
<View style={Style1.ModalView}>
<TouchableWithoutFeedback onPress={this._closeFilterModel}>
<View style={Style1.ModalCloseButton}>
<Icon
color="#7BB141"
name="check"
size={widthPercentageToDP("8%")}
/>
</View>
</TouchableWithoutFeedback>
</View>
</View>
</Modal>
</View>
}
SideMenu:
import { NavigationActions } from "react-navigation";
class SideMenu extends Component {
constructor(props) {
super(props);
this.state = { selected: 1, Language:props.screenProps.Language };
this.changer = this.changer.bind(this);
}
navigateToScreen = (route, num) => () => {
const navigateAction = NavigationActions.navigate({ routeName: route });
this.changer(num);
this.props.navigation.dispatch(navigateAction);
};
changer(Num) {
this.setState({ selected: Num });
}
render() {
const { Language } = this.state;
const color1 = "#0DA4D0",
color2 = "grey";
return (
<View style={Style.Parentcontainer}>
<TouchableWithoutFeedback onPress={this.navigateToScreen("Main", 1)}>
<View style={Style.ChildUpperContainer}>
<Icon
name="home-outline"
size={widthPercentageToDP("7%")}
color={this.state.selected === 1 ? color1 : color2}
/>
<Text
style={[
Style.textFont,
this.state.selected === 1
? { color: color1 }
: { color: color2 }
]}
>
Home
</Text>
</View>
</TouchableWithoutFeedback>
{this.state.selected === 1 && (
<TouchableWithoutFeedback
onPress={() => {
////////////////////(Here I want The Function Of Screen to be access)/////////////////////////
this.props.navigation.closeDrawer();
}}
>
<View style={Style.ChildUpperContainer}>
<Icon
name="filter-outline"
size={widthPercentageToDP("7%")}
color={color2}
/>
<Text style={[Style.textFont, { color: color2 }]}>
Home Filter
</Text>
</View>
</TouchableWithoutFeedback>
)}
<TouchableWithoutFeedback
onPress={this.navigateToScreen("LikeScreen", 3)}
>
<View style={Style.ChildUpperContainer}>
<Icon
name="thumb-up-outline"
size={widthPercentageToDP("7%")}
color={this.state.selected === 3 ? color1 : color2}
/>
<Text
style={[
Style.textFont,
this.state.selected === 3
? { color: color1 }
: { color: color2 }
]}
>
Liked
</Text>
</View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback
onPress={this.navigateToScreen("DislikeScreen", 4)}
>
<View style={Style.ChildUpperContainer}>
<Icon
name="thumb-down-outline"
size={widthPercentageToDP("7%")}
color={this.state.selected === 4 ? color1 : color2}
/>
<Text
style={[
Style.textFont,
this.state.selected === 4
? { color: color1 }
: { color: color2 }
]}
>
Disliked
</Text>
</View>
</TouchableWithoutFeedback>
</View>
);
}
}
SideMenu.propTypes = {
navigation: PropTypes.object
};
export default SideMenu;
In the sidemenu ,I commented where I want to access MainScreen's Function _OpenFilterModel to be performed.
Actually I want to open the Modal of screen (which will perform more operation on current screen Component) through clicking on menu of Drawer in which screen Component itself is a child.
I end up with my own following solution:
In MainScreen:
componentWillMount() {
this.props.navigation.setParams({
FilterModel: this._OpenFilterModel
});
}
In SideMenu:
onPress={() => {
////HERE TO CAll
this.props.navigation.state.routes[0].params.FilterModel();
this.props.navigation.closeDrawer();
}}
or
onPress={() => {
////HERE TO CAll
this.props.items[0].params.FilterModel();
this.props.navigation.closeDrawer();
}}
routes[0] and items[0] is accordingly to createDrawerNavigator Screen Sequence . Main Screen Is at index 0.