I am using a react-native Modal, and I am trying to get the background to dim to a dark grey when it opens. I can't seem to get it to do this! I have tried adding a Main View and setting the backgroundColor of that to dark grey when the modal is opened, but it doesn't work. I have also tried setting the backgroundColor of the Modal to be dark grey when it opens - also doesn't work. How can I achieve this please? This is my code:
Link to Snack: https://snack.expo.dev/#steph510/simple-modal
App.js
import * as React from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import Sortby from './components/Sortby';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default class App extends React.Component {
state = {
showSortby: false,
};
startSortByHandler = () => {
this.setState({
showSortby: true,
});
};
endSortByHandler = () => {
this.setState({
showSortby: false,
});
};
getSortValues = () => {
this.endSortByHandler()
}
getShowInGridViewList = () => {
const gridFieldArray = [
{"text":"Organization","key":"0.7204364607892255"},
{"text":"Document No","key":"0.11948720939854396"},
{"text":"Warehouse","key":"0.5981352662697218"},
{"text":"Business Partner","key":"0.3617080891091381"},
{"text":"Partner Address","key":"0.9242697027340077"},
{"text":"Movement Date","key":"0.19100558269330914"}]
return gridFieldArray;
};
render() {
return (
<View style={styles.container}>
<Card>
<Sortby
visible={this.state.showSortby}
onCancel={this.endSortByHandler}
showInGridViewList={this.getShowInGridViewList}
onOK={this.getSortValues}
></Sortby>
<Button title={'Open Modal'} onPress={this.startSortByHandler}></Button>
</Card>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#FFFFCC',
padding: 8,
}
});
SortBy.js
import React from "react";
import {View, Text, Modal, StyleSheet, Button, FlatList,} from "react-native";
import { RadioButton } from "react-native-paper";
export default class Sortby extends React.Component {
constructor(props) {
super(props);
}
state = {
selectedIndex: 0,
radioButtonValue: 'asc',
};
onRadiochange = (index, value) => {
this.setState({
radioButtonValue: value,
selectedIndex: index
});
};
render() {
return (
<Modal visible={this.props.visible} transparent={true}>
<View style={styles.modalStyles}>
<View style={styles.fieldsContainer}>
<FlatList
data={this.props.showInGridViewList()}
extraData={this.state}
renderItem={(itemData) => {
const index = itemData.index;
return (
<View style={styles.fieldItem}>
<Text style={styles.fieldText}>{itemData.item.text}</Text>
<View style={styles.radioButtonContainer}>
<RadioButton.Group onValueChange={value => this.onRadiochange(index, value)}>
<View style={styles.singleRadioButtonContainer}>
<Text>Asc</Text>
<RadioButton
color='#5d86d7'
value="asc"
status={ this.state.selectedIndex === index && this.state.radioButtonValue === 'asc' ? 'checked' : 'unchecked'}
/>
</View>
<View style={styles.singleRadioButtonContainer}>
<Text>Desc</Text>
<RadioButton
color='#5d86d7'
value="desc"
status={ this.state.selectedIndex === index && this.state.radioButtonValue === 'desc' ? 'checked' : 'unchecked'}
/>
</View>
</RadioButton.Group>
</View>
</View>
);
}}
alwaysBounceVertical={false}
/>
</View>
<View style={styles.buttonContainer}>
<View style={styles.button}>
<Button title="OK" color={"#5d86d7"} onPress={this.props.onOK}></Button>
</View>
<View style={styles.button}>
<Button
title="Cancel"
color={"#5d86d7"}
onPress={this.props.onCancel}
></Button>
</View>
</View>
</View>
</Modal>
);
}
}
const styles = StyleSheet.create({
modalStyles: {
height: "auto",
width: "90%",
flexDirection: "column",
justifyContent: "flex-start",
alignItems: "center",
backgroundColor: "#fff",
borderColor: "#777",
borderWidth: 1,
marginLeft: 20,
},
fieldsContainer: {
width: "100%",
},
fieldItem: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingLeft: 12,
borderBottomWidth: 1,
borderBottomColor: "#ebebeb",
},
fieldText: {
color: "#444",
},
radioButtonContainer: {
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
},
singleRadioButtonContainer: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginRight: 10,
},
buttonContainer: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
},
button: {
width: "100%",
marginHorizontal: 8,
},
});
Here is a solution I found: https://snack.expo.dev/C1gQM9bvD
I assume that the Modal from react-native does not support this directly since in their docs they do not mention anything like this.
However, you can check this library, I used it multiple times and you can customize it.
I have created a container style then I applied the rgba values for backgroundColor e.g:
modalStyles:{
flex: 1,
//backgroundColor: 'transparent',
backgroundColor: 'rgba(0,0,0,0.7)',
alignItems: 'center',
justifyContent: 'center',
},
Then inside the modal I created my actual modal dialog inside it.
Did you try the customBackdrop prop?
<Modal
visible={this.props.visible}
statusBarTranslucent={true}
customBackdrop={<View style={{backgroundColor: '#FFFFCC'} />}
>
Related
I have a modal component (Sortby.js) with a FlatList, and each list item has two radio buttons with 'asc' and 'desc' values. When a user selects a radio button, the state in the modal component is updated with the index of the list and the value of the button pressed. A user can only select one button.
When the user presses "OK" on the modal, I need to somehow get the index of the list and value of the radio button ('asc' or 'desc') sent to the parent component. How can I do this? Been stuck on this for ages now. Code is below, link to the Snack is here: https://snack.expo.dev/#steph510/send-radio-button-index-and-values-to-parent-on-modal-close
Sortby.js
import {View, Text, Modal, StyleSheet, Button, FlatList,} from "react-native";
import { RadioButton } from "react-native-paper";
export default class Sortby extends React.Component {
constructor(props) {
super(props);
}
state = {
selectedIndex: 0,
radioButtonValue: 'asc',
};
onRadiochange = (index, value) => {
this.setState({
radioButtonValue: value,
selectedIndex: index
});
};
render() {
return (
<Modal visible={this.props.visible} transparent={true}>
<View style={styles.modalStyles}>
<View style={styles.fieldsContainer}>
<FlatList
data={this.props.showInGridViewList()}
extraData={this.state}
renderItem={(itemData) => {
const index = itemData.index;
return (
<View style={styles.fieldItem}>
<Text style={styles.fieldText}>{itemData.item.text}</Text>
<View style={styles.radioButtonContainer}>
<RadioButton.Group onValueChange={value => this.onRadiochange(index, value)}>
<View style={styles.singleRadioButtonContainer}>
<Text>Asc</Text>
<RadioButton
color='#5d86d7'
value="asc"
status={ this.state.selectedIndex === index && this.state.radioButtonValue === 'asc' ? 'checked' : 'unchecked'}
/>
</View>
<View style={styles.singleRadioButtonContainer}>
<Text>Desc</Text>
<RadioButton
color='#5d86d7'
value="desc"
status={ this.state.selectedIndex === index && this.state.radioButtonValue === 'desc' ? 'checked' : 'unchecked'}
/>
</View>
</RadioButton.Group>
</View>
</View>
);
}}
alwaysBounceVertical={false}
/>
</View>
<View style={styles.buttonContainer}>
<View style={styles.button}>
<Button title="OK" color={"#5d86d7"} onPress={this.props.onOK}></Button>
</View>
<View style={styles.button}>
<Button
title="Cancel"
color={"#5d86d7"}
onPress={this.props.onCancel}
></Button>
</View>
</View>
</View>
</Modal>
);
}
}
const styles = StyleSheet.create({
modalStyles: {
height: "auto",
width: "90%",
flexDirection: "column",
justifyContent: "flex-start",
alignItems: "center",
backgroundColor: "#fff",
borderColor: "#777",
borderWidth: 1,
marginLeft: 20,
},
fieldsContainer: {
width: "100%",
},
fieldItem: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingLeft: 12,
borderBottomWidth: 1,
borderBottomColor: "#ebebeb",
},
fieldText: {
color: "#444",
},
radioButtonContainer: {
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
},
singleRadioButtonContainer: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginRight: 10,
},
buttonContainer: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
},
button: {
width: "100%",
marginHorizontal: 8,
},
});
App.js
import * as React from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import Sortby from './components/Sortby';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
export default class App extends React.Component {
state = {
showSortby: false,
};
startSortByHandler = () => {
this.setState({
showSortby: true,
});
};
endSortByHandler = () => {
this.setState({
showSortby: false,
});
};
getSortValues = () => {
this.endSortByHandler()
}
getShowInGridViewList = () => {
const gridFieldArray = [
{"text":"Organization","key":"0.7204364607892255"},
{"text":"Document No","key":"0.11948720939854396"},
{"text":"Warehouse","key":"0.5981352662697218"},
{"text":"Business Partner","key":"0.3617080891091381"},
{"text":"Partner Address","key":"0.9242697027340077"},
{"text":"Movement Date","key":"0.19100558269330914"}]
return gridFieldArray;
};
render() {
return (
<View style={styles.container}>
<Card>
<Sortby
visible={this.state.showSortby}
onCancel={this.endSortByHandler}
showInGridViewList={this.getShowInGridViewList}
onOK={this.getSortValues}
></Sortby>
<Button title={'Open Modal'} onPress={this.startSortByHandler}></Button>
</Card>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
}
});
There is a pattern called Lifting Up State where sharing the state is accomplished by moving it up to the closest common ancestor of the components that need it.
A state is created in the parent component and the setter for that state is passed to the child component.
That way, whenever the state is setted in the child component, you can manage it in the parent component too.
Create state in parent component and pass it to your child component
I have a FlatList, and each item in the List has two radio buttons - one for ascending and one for descending. My code currently allows a user to select either ascending or descending for the first list item, but it will not allow any of the radio buttons to be selected for the other list items (note: only ONE radio button should be selected at any one time). This is because when a radio button is pressed, the state is only being updated with the value of the button ('asc' or 'desc') but not the index of the list item as well. I am struggling to figure out how to update both of these using either onPress (on the RadioButton), or onValueChange (on RadioButton.Group).
How can I update both of these states when a radio button is selected, so that the buttons will work on the other list items and not just the first one?
Link to Snack is here: https://snack.expo.dev/#steph510/multiple-react-radio-buttons
Code is below:
import {View, Text, Modal, StyleSheet, Button, FlatList,} from "react-native";
import { RadioButton } from "react-native-paper";
export default class Sortby extends React.Component {
constructor(props) {
super(props);
}
state = {
selectedIndex: 0,
radioButtonValue: 'asc',
};
onPress = (index) => {
this.setState({
selectedIndex: index,
});
}
onRadiochange = value => {
this.setState({
radioButtonValue: value,
});
};
datalist = () => {
const gridFieldArray = [
{"text":"Organization","key":"0.6722908010549572"},
{"text":"Document No","key":"0.13707867638770266"},
{"text":"Warehouse","key":"0.5240454674464342"},
{"text":"Business Partner","key":"0.09679684535706568"},
{"text":"Partner Address","key":"0.5778522746749319"},
{"text":"Movement Date","key":"0.40039870656646404"}
]
return gridFieldArray;
};
render() {
return (
<Modal visible={this.props.visible} transparent={true}>
<View style={styles.modalStyles}>
<View style={styles.fieldsContainer}>
<FlatList
data={this.datalist()}
extraData={this.state}
renderItem={(itemData) => {
const index = itemData.index;
return (
<View style={styles.fieldItem}>
<Text style={styles.fieldText}>{itemData.item.text}</Text>
<View style={styles.radioButtonContainer}>
<RadioButton.Group onValueChange={this.onRadiochange}>
<View style={styles.singleRadioButtonContainer}>
<Text>Asc</Text>
<RadioButton
color='#5d86d7'
value="asc"
status={ this.state.selectedIndex === index && this.state.radioButtonValue === 'asc' ? 'checked' : 'unchecked'}
onPress={() => {this.onPress(index)}}
/>
</View>
<View style={styles.singleRadioButtonContainer}>
<Text>Desc</Text>
<RadioButton
color='#5d86d7'
value="desc"
status={ this.state.selectedIndex === index && this.state.radioButtonValue === 'desc' ? 'checked' : 'unchecked'}
onPress={() => {this.onPress(index)}}
/>
</View>
</RadioButton.Group>
</View>
</View>
);
}}
alwaysBounceVertical={false}
/>
</View>
<View style={styles.buttonContainer}>
<View style={styles.button}>
<Button title="OK" color={"#5d86d7"}></Button>
</View>
<View style={styles.button}>
<Button
title="Cancel"
color={"#5d86d7"}
onPress={this.props.onCancel}
></Button>
</View>
</View>
</View>
</Modal>
);
}
}
const styles = StyleSheet.create({
modalStyles: {
height: "auto",
width: "90%",
flexDirection: "column",
justifyContent: "flex-start",
alignItems: "center",
backgroundColor: "#fff",
borderColor: "#777",
borderWidth: 1,
paddingTop: 15,
marginLeft: 20,
marginTop: 50,
},
fieldsContainer: {
width: "100%",
},
fieldItem: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingLeft: 12,
borderBottomWidth: 1,
borderBottomColor: "#ebebeb",
},
fieldText: {
color: "#444",
},
radioButtonContainer: {
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
},
singleRadioButtonContainer: {
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
marginRight: 10,
},
buttonContainer: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginTop: 20,
marginBottom: 20,
},
button: {
width: "20%",
marginHorizontal: 8,
},
});
I am adding my now working solution here:
import {View, Text, Modal, StyleSheet, Button, FlatList,} from "react-native";
import { RadioButton } from "react-native-paper";
export default class Sortby extends React.Component {
constructor(props) {
super(props);
}
state = {
selectedIndex: 0,
radioButtonValue: 'asc',
};
onPress = (index) => {
this.setState({
selectedIndex: index,
});
}
onRadiochange = (index, value) => {
this.setState({
radioButtonValue: value,
selectedIndex: index
});
};
datalist = () => {
const gridFieldArray = [
{"text":"Organization","key":"0.6722908010549572"},
{"text":"Document No","key":"0.13707867638770266"},
{"text":"Warehouse","key":"0.5240454674464342"},
{"text":"Business Partner","key":"0.09679684535706568"},
{"text":"Partner Address","key":"0.5778522746749319"},
{"text":"Movement Date","key":"0.40039870656646404"}
]
return gridFieldArray;
};
render() {
return (
<Modal visible={this.props.visible} transparent={true}>
<View style={styles.modalStyles}>
<View style={styles.fieldsContainer}>
<FlatList
data={this.datalist()}
extraData={this.state}
renderItem={(itemData) => {
const index = itemData.index;
return (
<View style={styles.fieldItem}>
<Text style={styles.fieldText}>{itemData.item.text}</Text>
<View style={styles.radioButtonContainer}>
<RadioButton.Group onValueChange={value => this.onRadiochange(index, value)}>
<View style={styles.singleRadioButtonContainer}>
<Text>Asc</Text>
<RadioButton
color='#5d86d7'
value="asc"
status={ this.state.selectedIndex === index && this.state.radioButtonValue === 'asc' ? 'checked' : 'unchecked'}
onPress={() => {this.onPress(index)}}
/>
</View>
<View style={styles.singleRadioButtonContainer}>
<Text>Desc</Text>
<RadioButton
color='#5d86d7'
value="desc"
status={ this.state.selectedIndex === index && this.state.radioButtonValue === 'desc' ? 'checked' : 'unchecked'}
onPress={() => {this.onPress(index)}}
/>
</View>
</RadioButton.Group>
</View>
</View>
);
}}
alwaysBounceVertical={false}
/>
</View>
<View style={styles.buttonContainer}>
<View style={styles.button}>
<Button title="OK" color={"#5d86d7"}></Button>
</View>
<View style={styles.button}>
<Button
title="Cancel"
color={"#5d86d7"}
onPress={this.props.onCancel}
></Button>
</View>
</View>
</View>
</Modal>
);
}
}
const styles = StyleSheet.create({
modalStyles: {
height: "auto",
width: "90%",
flexDirection: "column",
justifyContent: "flex-start",
alignItems: "center",
backgroundColor: "#fff",
borderColor: "#777",
borderWidth: 1,
paddingTop: 15,
marginLeft: 20,
marginTop: 50,
},
fieldsContainer: {
width: "100%",
},
fieldItem: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingLeft: 12,
borderBottomWidth: 1,
borderBottomColor: "#ebebeb",
},
fieldText: {
color: "#444",
},
radioButtonContainer: {
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
},
singleRadioButtonContainer: {
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
marginRight: 10,
},
buttonContainer: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginTop: 20,
marginBottom: 20,
},
button: {
width: "20%",
marginHorizontal: 8,
},
});```
You'll need to keep track of the radio button state for each index. Right now you only have one piece of "global" state that each component in the list relies on. You could set up that state as an object instead:
state = {
selectedIndex: 0,
radioButtonValues: {},
};
...
onRadiochange = (index, value) => {
this.setState({
radioButtonValues: {
...this.state.radioButtonValues,
[index]: value,
}
});
};
...
// in render
<RadioButton.Group onValueChange={value => this.onRadiochange(index, value)}>
If nothing at this (parent) level needs to know about the ascending/descending of the internal list, consider moving the component defined inline in your renderItem out to its own component with its own state. Then you wouldn't need to know the index of the item to set the sort order, since each item would only affect itself. You would have to pass in the setter for the selected index to the new component. If this doesn't make sense and an example would help let me know.
This is the solution that I came up with. Thanks to all who assisted:
import {View, Text, Modal, StyleSheet, Button, FlatList,} from "react-native";
import { RadioButton } from "react-native-paper";
export default class Sortby extends React.Component {
constructor(props) {
super(props);
}
state = {
selectedIndex: 0,
radioButtonValue: 'asc',
};
onPress = (index) => {
this.setState({
selectedIndex: index,
});
}
onRadiochange = (index, value) => {
this.setState({
radioButtonValue: value,
selectedIndex: index
});
};
datalist = () => {
const gridFieldArray = [
{"text":"Organization","key":"0.6722908010549572"},
{"text":"Document No","key":"0.13707867638770266"},
{"text":"Warehouse","key":"0.5240454674464342"},
{"text":"Business Partner","key":"0.09679684535706568"},
{"text":"Partner Address","key":"0.5778522746749319"},
{"text":"Movement Date","key":"0.40039870656646404"}
]
return gridFieldArray;
};
render() {
return (
<Modal visible={this.props.visible} transparent={true}>
<View style={styles.modalStyles}>
<View style={styles.fieldsContainer}>
<FlatList
data={this.datalist()}
extraData={this.state}
renderItem={(itemData) => {
const index = itemData.index;
return (
<View style={styles.fieldItem}>
<Text style={styles.fieldText}>{itemData.item.text}</Text>
<View style={styles.radioButtonContainer}>
<RadioButton.Group onValueChange={value => this.onRadiochange(index, value)}>
<View style={styles.singleRadioButtonContainer}>
<Text>Asc</Text>
<RadioButton
color='#5d86d7'
value="asc"
status={ this.state.selectedIndex === index && this.state.radioButtonValue === 'asc' ? 'checked' : 'unchecked'}
onPress={() => {this.onPress(index)}}
/>
</View>
<View style={styles.singleRadioButtonContainer}>
<Text>Desc</Text>
<RadioButton
color='#5d86d7'
value="desc"
status={ this.state.selectedIndex === index && this.state.radioButtonValue === 'desc' ? 'checked' : 'unchecked'}
onPress={() => {this.onPress(index)}}
/>
</View>
</RadioButton.Group>
</View>
</View>
);
}}
alwaysBounceVertical={false}
/>
</View>
<View style={styles.buttonContainer}>
<View style={styles.button}>
<Button title="OK" color={"#5d86d7"}></Button>
</View>
<View style={styles.button}>
<Button
title="Cancel"
color={"#5d86d7"}
onPress={this.props.onCancel}
></Button>
</View>
</View>
</View>
</Modal>
);
}
}
const styles = StyleSheet.create({
modalStyles: {
height: "auto",
width: "90%",
flexDirection: "column",
justifyContent: "flex-start",
alignItems: "center",
backgroundColor: "#fff",
borderColor: "#777",
borderWidth: 1,
paddingTop: 15,
marginLeft: 20,
marginTop: 50,
},
fieldsContainer: {
width: "100%",
},
fieldItem: {
flexDirection: "row",
alignItems: "center",
justifyContent: "space-between",
paddingLeft: 12,
borderBottomWidth: 1,
borderBottomColor: "#ebebeb",
},
fieldText: {
color: "#444",
},
radioButtonContainer: {
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
},
singleRadioButtonContainer: {
flexDirection: "row",
justifyContent: "flex-start",
alignItems: "center",
marginRight: 10,
},
buttonContainer: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
marginTop: 20,
marginBottom: 20,
},
button: {
width: "20%",
marginHorizontal: 8,
},
});```
Hello this is my code. When I try to fill the text box then the error come i.e. ('this.setState is not a function.(In this.setState({emal:email)} this.setState is underfined').
Here is my code:
import React from 'react';
import {
Image,
Platform,
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
View,
TextInput,
TouchableHighlight,
Alert,
} from 'react-native';
export default function LoginScreen() {
onClickListener = (viewId) => {
Alert.alert("Alert", "You can't "+viewId);
}
return (
https://png.icons8.com/message/ultraviolet/50/3498db'}}/>
this.setState({email})}/>
<View style={styles.inputContainer}>
<Image style={styles.inputIcon} source={{uri: 'https://png.icons8.com/key-2/ultraviolet/50/3498db'}}/>
<TextInput style={styles.inputs}
placeholder="Password"
secureTextEntry={true}
underlineColorAndroid='transparent'
onChangeText={(password) => this.setState({password})}/>
</View>
<TouchableHighlight style={[styles.buttonContainer, styles.loginButton]} onPress={() => this.onClickListener('login')}>
<Text style={styles.loginText}>Login</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.buttonContainer} onPress={() => this.onClickListener('restore_password')}>
<Text>Forgot your password?</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.buttonContainer} onPress={() => this.onClickListener('register')}>
<Text>Register</Text>
</TouchableHighlight>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#DCDCDC',
},
inputContainer: {
borderBottomColor: '#F5FCFF',
backgroundColor: '#FFFFFF',
borderRadius:30,
borderBottomWidth: 1,
width:250,
height:45,
marginBottom:20,
flexDirection: 'row',
alignItems:'center'
},
inputs:{
height:45,
marginLeft:16,
borderBottomColor: '#FFFFFF',
flex:1,
},
inputIcon:{
width:30,
height:30,
marginLeft:15,
justifyContent: 'center'
},
buttonContainer: {
height:45,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginBottom:20,
width:250,
borderRadius:30,
},
loginButton: {
backgroundColor: "#00b5ec",
},
loginText: {
color: 'white',
}
});
That is the problem
export default function LoginScreen()
Change it to the
export default class LoginScreen extends Component
For using state, it must a stateful component rather than stateless component, So you have to change your functional component into Class.
change
export default function LoginScreen()
to
export default class LoginScreen extends React.Component
In react-native setState function has syntax
this.setState({someField:someValue})
you are using wrong syntax there, you have to give state name and value
this.setState({email})
this.setState({password})
these line should be like -
this.setState({ email: value })
this.setState({password: value })
if you want to use functional components you can use the UseState hook like this
by importing and initializing the state as shown below:
import React,{useState} from 'react';
export default function LoginScreen() {
const [email,setEmail]=useState(initialValues);
//setEmail function can be used for changing the state
}
use can see the usage of the useState here [https://reactjs.org/docs/hooks-state.html]
hope this helps for you
if you want to use functional components use react hooks,
otherwise use class component as below.
import React, { Component } from 'react';
import { Image, StyleSheet, Text, View, TextInput, TouchableHighlight, Alert } from 'react-native';
export default class LoginScreen extends Component {
onClickListener = viewId => {
Alert.alert('Alert', "You can't " + viewId);
};
render() {
return (
<View>
<View style={styles.inputContainer}>
<Image
style={styles.inputIcon}
source={{uri: 'https://png.icons8.com/key-2/ultraviolet/50/3498db'}}
/>
<TextInput
style={styles.inputs}
placeholder="Password"
secureTextEntry={true}
underlineColorAndroid="transparent"
onChangeText={password => this.setState({password})}
/>
</View>
<TouchableHighlight
style={[styles.buttonContainer, styles.loginButton]}
onPress={() => this.onClickListener('login')}>
<Text style={styles.loginText}>Login</Text>
</TouchableHighlight>
<TouchableHighlight
style={styles.buttonContainer}
onPress={() => this.onClickListener('restore_password')}>
<Text>Forgot your password?</Text>
</TouchableHighlight>
<TouchableHighlight
style={styles.buttonContainer}
onPress={() => this.onClickListener('register')}>
<Text>Register</Text>
</TouchableHighlight>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#DCDCDC',
},
inputContainer: {
borderBottomColor: '#F5FCFF',
backgroundColor: '#FFFFFF',
borderRadius: 30,
borderBottomWidth: 1,
width: 250,
height: 45,
marginBottom: 20,
flexDirection: 'row',
alignItems: 'center',
},
inputs: {
height: 45,
marginLeft: 16,
borderBottomColor: '#FFFFFF',
flex: 1,
},
inputIcon: {
width: 30,
height: 30,
marginLeft: 15,
justifyContent: 'center',
},
buttonContainer: {
height: 45,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
marginBottom: 20,
width: 250,
borderRadius: 30,
},
loginButton: {
backgroundColor: '#00b5ec',
},
loginText: {
color: 'white',
},
});
for the love of God, every styling i put on the stylesheet doesn't change anything.
i tried style the view, sectionheader & sectionbox but no luck
i want to align 4 icons in the boxsection and text below then as such, please any help would be appreciated.
export default class HomePage extends Component {
render() {
return (
<View>
<SectionHeader title={'Food'} />
<View >
<SectionBox >
<Icon style={styles.icons} name="icon name" size={50} />
<Icon style={styles.icons} name="icon name" size={50} />
<Icon style={styles.icons} name="icon name" size={50} />
<Icon style={styles.icons} name="icon name" size={50} />
<Text style={styles.sectiontext}>burgers</Text>
</SectionBox>
</View>
const styles = StyleSheet.create({
icons: {
flexDirection: 'row',
paddingTop: 7,
paddingLeft: 5,
},
sectiontext: {
fontSize: 15,
fontWeight: 'bold',
paddingLeft: 5,
alignItems: 'center',
}
});
For the icons-containing-box you would need to indicate flexDirection and flexWrap, not directly on the icon's style. Then to get the text below each icon you need to wrap icon and text in its own view and give that 'column' direction.
import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { Ionicons } from '#expo/vector-icons';
import { Constants } from 'expo';
const ICON_SIZE = 70;
const FONT_SIZE = 18;
const getItem = () => (
<View style={styles.iconStyle}>
<Ionicons name="md-checkmark-circle" size={ICON_SIZE} color="green" />
<Text style={styles.textStyle}>name</Text>
</View>
);
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<View style={styles.iconContainer}>
{getItem()}
{getItem()}
{getItem()}
{getItem()}
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
iconContainer: {
width: ICON_SIZE * 2,
flexDirection: 'row',
flexWrap: 'wrap',
},
iconStyle: {
flexDirection: 'column',
alignItems: 'center',
padding: 5,
},
textStyle: {
fontSize: FONT_SIZE,
},
});
You need a view for each group of icon and text with a flexDirection: 'column' and one another view for each row (or column), like the example below:
https://snack.expo.io/HJY7IWsFm
Other option is to use a GridView lib:
https://github.com/saleel/react-native-super-grid
I am new to react native, and I have created one sample login form. In this form i want to align total view to center. I tried this way but not working, Can You guide me how to achieve this.
My login class is
import React, {Component} from 'react';
import {AppRegistry,Text, View,TextInput,TouchableOpacity,StyleSheet} from 'react-native';
export default class Login extends Component{
render(){
return(
<View style={styles.container}>
<TextInput style={styles.textInput} placeholder="Acc No/User ID"/>
<TextInput style={styles.textInput} placeholder="Password"/>
<TouchableOpacity style={styles.btn} onPress={this.login}><Text>Log In</Text></TouchableOpacity>
</View>
);
}
login=()=>{
alert("testing......");
// this.props.navigation.navigate('Second');
}
}
AppRegistry.registerComponent('Login', () => Login);
const styles = StyleSheet.create({
container:{
justifyContent: 'center',
alignItems: 'center',
},
header: {
fontSize: 24,
marginBottom: 60,
color: '#fff',
fontWeight: 'bold',
},
textInput: {
alignSelf: 'stretch',
padding: 10,
marginLeft: 80,
marginRight:80,
},
btn:{
alignSelf: 'stretch',
backgroundColor: '#01c853',
padding: 10,
marginLeft: 80,
marginRight:80,
alignItems: 'center',
}
});
And the following is the screen shot of above code.
And i tried with the bellow code, but not working
container:{
justifyContent: 'center',
alignItems: 'center',
flex:1
},
So please help me, how to do this?
Thanks In Advance..
Use the flex display : https://css-tricks.com/snippets/css/a-guide-to-flexbox/
import React, { Component } from 'react';
import { AppRegistry, Text, View, TextInput, TouchableOpacity, StyleSheet } from 'react-native';
export default class Login extends Component {
render() {
return (
<View style={styles.container}>
<TextInput style={styles.textInput} placeholder="Acc No/User ID" />
<TextInput style={styles.textInput} placeholder="Password" />
<TouchableOpacity style={styles.btn} onPress={this.login}><Text>Log In</Text></TouchableOpacity>
</View>
);
}
login = () => {
alert("testing......");
// this.props.navigation.navigate('Second');
}
}
AppRegistry.registerComponent('Login', () => Login);
const styles = StyleSheet.create({
container: {
display: 'flex',
flexDirection: 'column',
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
header: {
fontSize: 24,
color: '#fff',
fontWeight: 'bold',
},
textInput: {
padding: 10,
textAlign: 'center',
},
btn: {
backgroundColor: '#01c853',
paddingVertical: 10,
paddingHorizontal: 50,
}
});
And by the way, you could have easily found an answer with a simple search (Vertically center view react-native) : https://moduscreate.com/blog/aligning-children-using-flexbox-in-react-native/
just add flex :1 to your container style
container:{
flex:1,
justifyContent: 'center',
alignItems: 'center',
}
import React,{Component} from 'react';
import {View,Text,TextInput, Button,StyleSheet,Alert} from 'react-native';
class App extends Component{
state = {
userId:'',
password:'',
};
render(){
return(
<View style={styles.container}>
<View>
</View>
<View>
<TextInput
placeholder="User ID"
style={styles.loginTextInput}
onChangeText={(value) => this.setState({userId: value})}
value={this.state.userId}
></TextInput>
<TextInput
placeholder="Password"
style={styles.loginTextInput}
onChangeText={(value)=>this.setState({password:value})}
></TextInput>
<Button
title="Login"
style={styles.loginBtn}
onPress={this.loginCheck}
></Button>
</View>
</View>
)
}
loginCheck=()=>{
if((this.state.userId=='admin') && (this.state.password=='admin')){
Alert.alert("Login Success");
}else{
Alert.alert("User and password is not match\n Please try again");
}
}
}
export default App;
const styles = StyleSheet.create({
container:{
flex:1,
justifyContent:'center',
},
loginTextInput:{
borderColor:'#ebe9e6',
borderWidth:1,
margin:5,
},
loginBtn:{
backgroundColor: '#01c853',
paddingVertical: 10,
paddingHorizontal: 50,
}
})