React-Native ListView with Object Array - arrays

Hey all would love some help will this question.. I have been tearing my hair out!
I'm trying to render a ListView using an array of objects of the form:
Array[number]
0: Object
category: ''
date: ''
total: ''
vendor: ''
1: Object ..etc.
I am using the component react-native-swipe-list-view found here: swipeList github
But I'm only rendering the last element of my array of data objects! I'm also using redux in this react-native application although I don't see this having any effect
HELP ! :)
Output is as follows
Here is my current code.
import React, {
Component,
} from 'react';
import {
ListView,
Text,
TouchableOpacity,
TouchableHighlight,
View,
Alert
} from 'react-native';
import { connect } from 'react-redux';
import { Actions } from 'react-native-router-flux';
import { SwipeListView } from 'react-native-swipe-list-view';
import {
PRIMARY_HIGHLIGHT_COLOUR,
CARD_BACKGROUND_COLOUR,
BORDER_COLOUR
} from '../global/colours';
import {
MySearchBar,
Button,
FAB,
BackgroundView,
} from '../components';
import { HEADER } from '../global/margins';
class ReceiptsListView extends Component {
constructor(props) {
super(props);
console.log(this.props.receiptList);
this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
this.state = {
listViewData: this.ds.cloneWithRows(this.props.receiptList)
};
console.log('state', this.state);
}
/* shouldComponentUpdate(nextProps) {
if (this.props !== nextProps) {
return true;
}
return false;
} */
deleteRow(secId, rowId, rowMap) {
// rowMap[`${secId}${rowId}`].closeRow();
//console.log('delete', secId, rowId, rowMap);
// const newData = [...this.state.listViewData];
// newData.splice(rowId, 1);
// this.setState({ listViewData: newData });
}
render() {
//const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
//const dataSource = ds.cloneWithRows(receiptlist);
//this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
return (
<BackgroundView style={styles.container}>
<View style={styles.search}>
<MySearchBar />
<Button style={styles.button}> Export </Button>
</View>
<SwipeListView
dataSource={this.state.listViewData}
renderRow={(data) => this.renderRow(data)}
renderHiddenRow={(secId, rowId, rowMap) => this.renderHiddenRow(secId, rowId, rowMap)}
rightOpenValue={-150}
recalculateHiddenLayout
previewFirstRow
/>
<FAB
onPress={this.onPressFAB}
/>
</BackgroundView>
);
}
renderRow(data) {
console.log('data', data);
return (
<TouchableHighlight
onPress={console.log('You touched me')}
style={styles.rowFront}
underlayColor={'#AAA'}
>
<View>
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }} >
<Text> {`${data.vendor}`} </Text>
<Text> {`${data.total}`} </Text>
</View>
<View>
<Text> {`${data.date}`} </Text>
<Text> {`${data.category}`} </Text>
</View>
</View>
</TouchableHighlight>
);
}
renderHiddenRow(secId, rowId, rowMap) {
return (
<View style={styles.rowBack}>
<TouchableOpacity
style={[styles.backRightBtn, styles.backRightBtnLeft]}
onPress={_ => (console.log(secId, rowId, rowMap))}
>
<Text style={styles.backTextWhite}>Export</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.backRightBtn, styles.backRightBtnRight]}
onPress={_ => (console.log(secId, rowId, rowMap))}
>
<Text style={styles.backTextWhite}>Delete</Text>
</TouchableOpacity>
</View>
);
}
onPressFAB() {
console.log('FAB pressed');
Alert.alert(
'Choose Photo Source',
null,
[
{ text: 'Camera', onPress: () => Actions.camera() },
{ text: 'Photo Library', onPress: () => Actions.photos() },
{ text: 'Cancel', onPress: () => console.log('cancel'), style: 'cancel' }
]
);
}
}
const styles = {
search: {
flexDirection: 'row',
padding: 10,
height: 60,
backgroundColor: PRIMARY_HIGHLIGHT_COLOUR
},
button: {
marginTop: 0,
height: 30,
flexGrow: 0.3
},
container: {
padding: 0,
paddingTop: HEADER.height
},
rowFront: {
//alignItems: 'center',
flex: 1,
padding: 10,
backgroundColor: CARD_BACKGROUND_COLOUR,
borderBottomColor: BORDER_COLOUR,
borderBottomWidth: 1,
justifyContent: 'center',
//height: 100,
},
rowBack: {
alignItems: 'center',
backgroundColor: '#DDD',
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
paddingLeft: 15,
},
backRightBtn: {
alignItems: 'center',
bottom: 0,
justifyContent: 'center',
position: 'absolute',
top: 0,
width: 75
},
backRightBtnLeft: {
backgroundColor: 'blue',
right: 75
},
backRightBtnRight: {
backgroundColor: 'red',
right: 0
},
controls: {
alignItems: 'center',
marginBottom: 30
},
switchContainer: {
flexDirection: 'row',
justifyContent: 'center',
marginBottom: 5
},
switch: {
alignItems: 'center',
borderWidth: 1,
borderColor: 'black',
paddingVertical: 10,
width: 100,
}
};
const mapStateToProps = ({ receipts, accounts }) => {
const {
myReceipts,
receiptList
} = receipts;
const {
labelsArray
} = accounts;
return {
myReceipts,
receiptList,
labelsArray
};
};
export default connect(mapStateToProps, {
})(ReceiptsListView);

the issue was the flex:1 in styling of the renderRow (styles.
rowFront)
Below is the working code as I'm sure it can be helpful to others.
import React, {
Component,
} from 'react';
import {
ListView,
Text,
TouchableOpacity,
TouchableHighlight,
View,
Alert,
TextInput
} from 'react-native';
import { connect } from 'react-redux';
import { Actions } from 'react-native-router-flux';
import { SwipeListView } from 'react-native-swipe-list-view';
import Icon from 'react-native-vector-icons/FontAwesome';
import Spinner from 'react-native-loading-spinner-overlay';
import {
PRIMARY_HIGHLIGHT_COLOUR,
CARD_BACKGROUND_COLOUR,
BORDER_COLOUR,
SHADOW_COLOUR
} from '../global/colours';
import {
Button,
FAB,
BackgroundView,
TitleText
} from '../components';
import { HEADER } from '../global/margins';
import { searchTextChanged, deleteReceipt } from '../actions';
class ReceiptsListView extends Component {
constructor(props) {
super(props);
console.log(this.props.receiptList);
console.log(this.props.categories);
this.ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
}
shouldComponentUpdate(nextProps) {
if (this.props !== nextProps) {
return true;
} else if (this.props.searchQuery !== nextProps.searchQuery) {
return true;
}
return false;
}
render() {
if (this.props.receiptList.length < 1) {
return (
<BackgroundView style={styles.emptyContainer}>
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<TitleText> No Receipts </TitleText>
</View>
<FAB
onPress={this.onPressFAB}
/>
</BackgroundView>
);
}
return (
<BackgroundView style={styles.container}>
<View style={styles.search}>
<View style={{ flexGrow: 1, height: 35, paddingTop: 5 }}>
<View style={styles.searchStyle}>
<View style={styles.searchbar}>
<Icon
name="search"
size={15}
color="#ddd"
/>
<TextInput
style={{ flexGrow: 1, width: null, paddingLeft: 5 }}
placeholder='search'
placeholderTextColor='lightgray'
onChangeText={this.onSearchChange.bind(this)}
value={this.props.searchQuery}
onFocus={() => console.log('hi')}
/>
</View>
</View>
</View>
<Button
style={styles.button}
//onPress={this.searchText()}
>
Search
</Button>
</View>
<SwipeListView
dataSource={this.ds.cloneWithRows(this.props.receiptList)}
renderRow={(data) => this.renderRow(data)}
renderHiddenRow={(secId, rowId, rowMap) => this.renderHiddenRow(secId, rowId, rowMap)}
rightOpenValue={-150}
recalculateHiddenLayout
previewFirstRow
/>
<FAB
onPress={this.onPressFAB}
/>
<Spinner
visible={this.props.isFetching}
textContent={''}
textStyle={{ color: 'white' }}
/>
</BackgroundView>
);
}
onSearchChange(text) {
this.props.searchTextChanged(text);
}
renderRow(data) {
//console.log('data', data);
return (
<TouchableHighlight
onPress={() => console.log('You touched me', data)}
underlayColor={'#AAA'}
style={styles.rowFront}
>
<View>
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }} >
<Text> {`${data.vendor}`} </Text>
<Text> {`${data.total}`} </Text>
</View>
<View>
<Text> {`${data.date}`} </Text>
<Text> {`${data.category}`} </Text>
</View>
</View>
</TouchableHighlight>
);
}
renderHiddenRow(secId, rowId, rowMap) {
return (
<View style={styles.rowBack}>
<TouchableOpacity
style={[styles.backRightBtn, styles.backRightBtnLeft]}
onPress={() => (this.exportItem(secId, rowId, rowMap))}
>
<Text style={styles.backTextWhite}>Export</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.backRightBtn, styles.backRightBtnRight]}
onPress={() => (this.deleteItem(secId, rowId, rowMap))}
>
<Text style={styles.backTextWhite}>Delete</Text>
</TouchableOpacity>
</View>
);
}
deleteItem(secId, rowId, rowMap) {
console.log('secId', secId, 'rowId', rowId, 'rowMap', rowMap);
console.log('obj', secId.id, 'acc', this.props.curAccountID);
this.props.deleteReceipt(this.props.curAccountID, secId.id);
}
exportItem(secId, rowId, rowMap) {
console.log('secId', secId, 'rowId', rowId, 'rowMap', rowMap);
//this.props.exportReceipt(this.props.curAccountID, secId.id);
}
onPressFAB() {
console.log('FAB pressed');
Alert.alert(
'Choose Photo Source',
null,
[
{ text: 'Camera', onPress: () => Actions.camera() },
{ text: 'Photo Library', onPress: () => Actions.photos() },
{ text: 'Cancel', onPress: () => console.log('cancel'), style: 'cancel' }
]
);
}
}
const styles = {
search: {
flexDirection: 'row',
padding: 10,
height: 60,
backgroundColor: PRIMARY_HIGHLIGHT_COLOUR
},
searchbar: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
paddingLeft: 5
},
button: {
marginTop: 0,
height: 30,
flexGrow: 0.3
},
container: {
padding: 0,
paddingTop: HEADER.height
},
emptyContainer: {
flex: 1,
padding: 0,
paddingTop: HEADER.height,
justifyContent: 'center'
},
rowFront: {
//alignItems: 'center',
padding: 10,
backgroundColor: CARD_BACKGROUND_COLOUR,
borderBottomColor: BORDER_COLOUR,
borderBottomWidth: 1,
justifyContent: 'center',
//height: 100,
},
rowBack: {
alignItems: 'center',
backgroundColor: '#DDD',
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
paddingLeft: 15,
},
backRightBtn: {
alignItems: 'center',
bottom: 0,
justifyContent: 'center',
position: 'absolute',
top: 0,
width: 75
},
backRightBtnLeft: {
backgroundColor: 'blue',
right: 75
},
backRightBtnRight: {
backgroundColor: 'red',
right: 0
},
controls: {
alignItems: 'center',
marginBottom: 30
},
switchContainer: {
flexDirection: 'row',
justifyContent: 'center',
marginBottom: 5
},
switch: {
alignItems: 'center',
borderWidth: 1,
borderColor: 'black',
paddingVertical: 10,
width: 100,
},
searchStyle: {
flex: 1,
flexDirection: 'row',
alignSelf: 'stretch',
padding: 5,
justifyContent: 'flex-start',
alignItems: 'center',
backgroundColor: CARD_BACKGROUND_COLOUR,
borderRadius: 10,
borderWidth: 1,
borderColor: 'grey',
marginLeft: 5,
marginRight: 5,
shadowColor: SHADOW_COLOUR,
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 2,
},
};
const mapStateToProps = ({ accounts, receipts, searchIt }) => {
const {
curAccountID
} = accounts;
const {
searchQuery
} = searchIt;
const {
isFetching,
myReceipts,
receiptList,
categories
} = receipts;
return {
curAccountID,
isFetching,
myReceipts,
receiptList,
searchQuery,
categories
};
};
export default connect(mapStateToProps, {
searchTextChanged, deleteReceipt
})(ReceiptsListView);

Related

How to Not change to initial state when other state change their value

Hello there I am phasing an logic issue where I don't want my other useState render(run) whenever another state change their value because it render full component every time so it initialize default values.
here when useEffect run and it change item value by setitem but after component run again so it initialize default again
import React, { useState, useEffect, useRef, useLayoutEffect } from "react";
import {
Image,
StyleSheet,
TouchableOpacity,
Text,
View,
SafeAreaView,
FlatList,
TextInput,
} from "react-native";
import { EvilIcons } from "#expo/vector-icons";
import { MaterialCommunityIcons, Ionicons } from "#expo/vector-icons";
import axios from "axios";
import { AsyncStorage } from "react-native";
import url from "../url";
const Handlenewspost = ({ navigation }) => {
var items = navigation.getParam("item");
var user = navigation.getParam("user");
var functionforoffset = navigation.getParam("functionforoffset");
const [item, setitem] = useState(items);
var like = item.like;
var found = like.find((element) => {
if (element.username === user.username) return true;
});
found ? (item.userlike = true) : false;
var checklike = "";
item.userlike ? (checklike = "heart") : (checklike = "heart-outline");
item.userlike ? (checkcolor = "red") : (checkcolor = "black");
const [likebutton, setlikebutton] = useState(checklike);
const [postlikes, setpostlikes] = useState(item.likes);
const [likebuttoncolor, setlikebuttoncolor] = useState(checkcolor);
useEffect(() => {
axios
.get(url + "post/byid/" + items._id)
.then((response) => {
setitem(response.data);
})
.catch((err) => {
console.log(err);
console.log(err.response.data.error);
Alert.alert("Something went wrong", err.response.data.error, [
{ text: "OK", onPress: () => console.log("OK Pressed") },
]);
});
}, []);
const onpresshandle = async (item) => {
userToken = await AsyncStorage.getItem("userToken");
id = item._id;
token = userToken;
functionforoffset();
axios
.post(url + "post/like", { token, id })
.then((response) => {
if (!response.data) {
} else {
}
})
.catch((err) => {
console.log(err);
console.log(err.response.data.error);
Alert.alert("Something went wrong", err.response.data.error, [
{ text: "OK", onPress: () => console.log("OK Pressed") },
]);
});
};
function checkcaption(caption) {
if (caption != "") {
return (
<SafeAreaView style={styles.safe}>
<View
style={[
styles.root,
{ flexDirection: "row", alignItems: "center" },
]}
>
<Text style={[styles.textStyle, { fontSize: 15, marginLeft: 0 }]}>
{item.caption}
</Text>
</View>
</SafeAreaView>
);
} else {
return <View></View>;
}
}
return (
<>
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.container}>
<View style={styles.card}>
<View style={styles.cardheader}>
{item.profileimage ? (
<Image
source={{ uri: url + "filename/" + item.profileimage }}
style={{
marginLeft: 16,
marginRight: 8,
height: 40,
width: 40,
borderRadius: 100,
}}
></Image>
) : (
<Image
source={require("../../assets/localbazilogo2.jpeg")}
style={[
styles.profileimage,
{ marginLeft: 16, marginRight: 5 },
]}
></Image>
)}
<Text style={{ fontWeight: "bold", fontSize: 15, marginLeft: 5 }}>
{item.username}
</Text>
</View>
<View style={styles.cardbody}>
{item.filename ? (
<Image
style={styles.cardbodyimage}
resizeMode="stretch"
source={{ uri: url + "filename/" + item.filename }}
></Image>
) : (
<View></View>
)}
</View>
<View style={styles.cardfooter}>
<MaterialCommunityIcons
onPress={() => {
if (item.userlike) {
setlikebutton("heart-outline");
setlikebuttoncolor("black");
setpostlikes(postlikes - 1);
} else {
setlikebutton("heart");
setlikebuttoncolor("red");
setpostlikes(postlikes + 1);
}
item.userlike = !item.userlike;
onpresshandle(item);
}}
name={likebutton}
size={28}
color={likebuttoncolor}
style={{ marginLeft: 10, marginTop: 4 }}
>
{" "}
</MaterialCommunityIcons>
<Text style={{ fontSize: 18, marginLeft: 1 }}>{postlikes}</Text>
<EvilIcons
name="comment"
size={30}
style={{ marginLeft: 20, marginTop: 4 }}
color="black"
/>
<Image
style={{ marginLeft: 20, marginTop: 4 }}
source={require("../../assets/share.png")}
></Image>
</View>
{checkcaption(item.caption)}
<View style={styles.showcomment}>
<Text>
View all {item.comments ? item.comments.length : 0} comments
</Text>
</View>
<View style={styles.comment}>
<View>
{user.profileimage ? (
<Image
source={{ uri: url + "filename/" + user.profileimage }}
style={{
height: 35,
width: 35,
borderRadius: 100,
marginLeft: 14,
}}
></Image>
) : (
<View></View>
)}
</View>
<View style={styles.addcomment}>
<Text
style={{
marginHorizontal: 5,
fontSize: 14,
color: "#9CA3AF",
width: 240,
}}
>
Add Comment
</Text>
</View>
</View>
</View>
</View>
</SafeAreaView>
</>
);
};
export default Handlenewspost;
const styles = StyleSheet.create({
showcomment: { marginLeft: 20, marginBottom: 5 },
addcomment: {
overflow: "hidden",
marginLeft: 20,
marginRight: 20,
padding: 7,
backgroundColor: "#E6E7E9",
borderRadius: 25,
},
comment: {
marginTop: 10,
flexDirection: "row",
alignItems: "center",
},
email: {
flexDirection: "row",
overflow: "hidden",
marginLeft: 20,
marginRight: 20,
marginTop: 10,
marginBottom: 20,
padding: 7,
backgroundColor: "#E6E7E9",
borderRadius: 25,
},
iconout: { width: "20%", alignItems: "center" },
icon: { height: 35, width: 35, resizeMode: "stretch" },
icons: {
flexDirection: "row",
flexWrap: "wrap",
marginTop: 1,
marginHorizontal: 28,
marginBottom: 20,
},
profileimage: {
width: "12%",
height: "170%",
borderRadius: 100,
resizeMode: "stretch",
},
safe: {
flex: 1,
marginTop: -10,
},
root: {
flex: 1,
padding: 16,
},
textStyle: {
fontSize: 14,
},
container: {
justifyContent: "center",
flex: 1,
},
cardfooter: {
flexDirection: "row",
alignItems: "center",
},
cardbodyimage: {
height: 350,
width: "100%",
marginTop: 3,
borderRadius: 3,
},
cardbody: {},
cardheader: {
flexDirection: "row",
alignItems: "center",
marginVertical: 12,
},
card: {
marginVertical: 10,
marginHorizontal: 4,
},
});

how to detect a face with react-native-camera facedetector?

I am trying to detect face with react-native-camera, I want to know how can we detect an individual's face, there is no proper documentation about the mlkit.
await FaceDetector.detectFacesAsync(data.uri) this statement is just returning face object like this face[0] = { bounds: { origin: { x: 739, y: 987 }, size: { x: 806, y: 789 } }, faceID: 0, rollAngle: 10.533509254455566, yawAngle: 0.7682874798774719 }.
This is just object's position, I cannot figure out how to recognize individual's face characteristics like eys, nose with the FaceDetector and suppose I will save person A's face data then how I will match the data with A's face later with react-native-camera ?
ML Kit does not support Face Recognition. Also, React Native is not officially supported (yet), but you could check out https://rnfirebase.io/ml-vision/face-detection#process which outlines how you can get a 133-point contour of the face. However, this is not meant for facial recognition, but rather for overlays (e.g. masks, filters).
import SplashScreen from 'react-native-splash-screen'
import React, { useEffect, createRef,useState } from 'react';
import { SafeAreaView, View, Image, StyleSheet, Text, Modal, TouchableOpacity } from 'react-native';
import { RNCamera } from 'react-native-camera';
const Test = (props) => {
useEffect(() => {
SplashScreen.hide();
});
const [faces, setFace] = useState([]);
const [faceavl, setFaceavl] = useState(false);
const [takeTimeFaceAvl, setTakeTimeFaceAvl] = useState(false);
const [searchWaiting, setsearchWaiting] = useState(null)
const [modalVisible, setModalVisible] = useState(false);
const [image, setImage] = useState(null);
const mycamera = createRef()
const PendingView = () => (
<View
style={{
flex: 1,
backgroundColor: 'lightgreen',
justifyContent: 'center',
alignItems: 'center',
}}
>
<Text>Waiting</Text>
</View>
);
const renderFaces = () => (
<View style={{
position: 'absolute',
bottom: 0,
right: 0,
left: 0,
top: 0,
}} pointerEvents="none">
{faces.map(renderFace)}
</View>
);
const renderFace = ({ bounds, faceID, rollAngle, yawAngle }) => (
<View
key={faceID}
transform={[
{ perspective: 600 },
{ rotateZ: `${rollAngle.toFixed(0)}deg` },
{ rotateY: `${yawAngle.toFixed(0)}deg` },
]}
style={[
{
padding: 10,
borderWidth: 1,
borderRadius: 2,
position: 'absolute',
borderColor: '#000',
justifyContent: 'center',
},
{
...bounds.size,
left: bounds.origin.x,
top: bounds.origin.y,
},
]}
>
</View>
);
return (
<>
<SafeAreaView style={styles.container}>
<RNCamera
ref={mycamera}
style={styles.preview}
type={RNCamera.Constants.Type.front}
flashMode={RNCamera.Constants.FlashMode.on}
androidCameraPermissionOptions={{
title: 'Permission to use camera',
message: 'We need your permission to use your camera',
buttonPositive: 'Ok',
buttonNegative: 'Cancel',
}}
androidRecordAudioPermissionOptions={{
title: 'Permission to use audio recording',
message: 'We need your permission to use your audio',
buttonPositive: 'Ok',
buttonNegative: 'Cancel',
}}
onFacesDetected={(data) => {
setFace(data.faces)
setFaceavl(true);
clearTimeout(searchWaiting)
const avc = setTimeout(() => {
console.log()
setFaceavl(false);
setFace([])
}, 500)
setsearchWaiting(avc)
}}
onFaceDetectionError={(error) => {
console.log('face--detact-->', error)
}}
>
{({ camera, status, recordAudioPermissionStatus }) => {
if (status !== 'READY') return <PendingView />;
return (
<View style={{ flex: 0, flexDirection: 'row', justifyContent: 'center' }}>
<TouchableOpacity onPress={async () => {
const options = { quality: 0.5, base64: true };
const data = await camera.takePictureAsync(options)
if (faceavl) {
setTakeTimeFaceAvl(true)
} else {
setTakeTimeFaceAvl(false)
}
console.log(data.uri)
setImage(data)
setModalVisible(!modalVisible)
}} style={styles.capture}>
<Text style={{ fontSize: 14 }}> SNAP </Text>
</TouchableOpacity>
</View>
);
}}
</RNCamera>
{faces ? renderFaces() : null}
</SafeAreaView>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert("Modal has been closed.");
setModalVisible(!modalVisible);
}}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
{takeTimeFaceAvl ? image ? <Image
style={{
width: 200,
height: 100,
}}
source={{
uri: image.uri,
}}
/> : null : <Text>Face not found</Text>}
<TouchableOpacity
style={[styles.button, styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}
>
<Text style={styles.textStyle}>Hide Modal</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
</>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: 'black',
},
item: {
backgroundColor: '#FFF',
},
viewOne: {
flexDirection: 'row'
},
viewTwo: {
alignItems: 'flex-end', marginEnd: 9
},
title: {
fontSize: 16, // Semibold #000000
color: '#000000',
},
noOff: {
color: '#D65D35',
fontSize: 20, // Semibold
}, product: {
color: '#A6A6A6',
fontSize: 16, // Regular
}, titleView: {
flex: 1,
alignSelf: 'center',
marginStart: 14,
marginEnd: 14,
},
centeredView: {
flex: 1,
justifyContent: "center",
alignItems: "center",
marginTop: 22
},
modalView: {
margin: 20,
backgroundColor: "white",
borderRadius: 20,
padding: 10,
alignItems: "center",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 2
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5
},
button: {
borderRadius: 20,
padding: 10,
elevation: 2
},
buttonOpen: {
backgroundColor: "#F194FF",
},
buttonClose: {
backgroundColor: "#2196F3",
},
textStyle: {
color: "white",
fontWeight: "bold",
textAlign: "center"
},
modalText: {
marginBottom: 15,
textAlign: "center"
},
preview: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
},
capture: {
flex: 0,
backgroundColor: '#fff',
borderRadius: 5,
padding: 15,
paddingHorizontal: 20,
alignSelf: 'center',
margin: 20,
},
});

How to select only one item from a flatlist in React and change it's style?

I'm stuck with trying to make a flatlist work with one selection and change only it's background. I already got the id from the pressed item and I'm passing the information to another page. But after clicking, it's style is not changing. I need to select just one and if I click on another it should deselect the first one and keep the new one selected.
My code is as folows:
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity, FlatList, Linking, ActivityIndicator } from 'react-native';
import { Searchbar } from 'react-native-paper';
export default class Merchants extends Component {
constructor() {
super()
this.state = {
search: '',
loading: false,
merchantObj: [],
btnDisabled: true,
itemId: null,
imgLink: null,
listClicked: false,
}
this.arrayholder = [];
}
componentDidMount() {
const merchantUrl = 'http://165.227.43.115:8080/merchant/merchant'
fetch(merchantUrl)
.then(response => response.json())
.then(data => {
this.setState({ merchantObj: data, loading: false },
function () {
this.arrayholder = data;
})
})
.catch(error => {
console.log(error)
});
}
search = text => {
console.log(text);
};
clear = () => {
this.search.clear();
};
SearchFilterFunction(text) {
//passing the inserted text in textinput
const newData = this.arrayholder.filter(function (item) {
//applying filter for the inserted text in search bar
const itemData = item.name ? item.name.toUpperCase() : ''.toUpperCase();
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
this.setState({
//setting the filtered newData on datasource
//After setting the data it will automatically re-render the view
merchantObj: newData,
search: text,
});
}
FlatListItemSeparator = () => {
return (
<View
style={{
height: 1,
width: "95%",
justifyContent: 'center',
backgroundColor: "#DCDCDC",
}}
/>
);
}
MerchSelected = (selectedId) => {
if (this.state.btnDisabled === true) {
return (
<View style={styles.btnDsb}>
<Text style={styles.txtBtn}>Select</Text>
</View>
)
} else {
return (
<TouchableOpacity onPress={(item) => this.props.navigation.navigate('Main', { itemId: this.state.itemId, itemImg: this.state.imgLink })}>
<View style={styles.btnSelect}>
<Text style={styles.txtBtn}>Select</Text>
</View>
</TouchableOpacity>
)
}
}
PressedItem = (itemId, itemImg) => {
console.log(itemId)
this.setState({ itemId: itemId, btnDisabled: false, imgLink: itemImg })
}
renderItem = ({ item }) => {
return (
<TouchableOpacity onPress={() => this.PressedItem(item.id, item.image)} >
<View style={styles.listItem} >
<Image
style={{ width: 80, height: 80 }}
source={{ uri: `${item.image}` }} />
<View style={{ flexDirection: 'column', marginLeft: 2 }}>
< Text style={{ fontWeight: 'bold', fontSize: 20 }} > {item.name} </Text>
{item.shoppingOption == 'STORE' ? <Text>Store</Text> : <Text>In-Store & Online</Text>}
<Text>${item.minAmount} - ${item.maxAmount}</Text>
<Text style={{ color: '#00CED1' }}
onPress={() => Linking.openURL(`${item.website}`)}>
view website
</Text>
</View>
</View>
</TouchableOpacity>
)
}
render() {
if (this.state.loading) {
return (
<View>
<Text>Loading...</Text>
</View>
);
}
return (
<View style={styles.container} >
<View style={styles.searchBar}>
<Searchbar
round
placeholder="Search"
onChangeText={text => this.SearchFilterFunction(text)}
onClear={text => this.SearchFilterFunction('')}
value={this.state.search}
/>
</View>
<View style={styles.merchantsList}>
<FlatList
data={this.state.merchantObj}
renderItem={this.renderItem}
ItemSeparatorComponent={this.FlatListItemSeparator}
keyExtractor={item => item.id.toString()}
extraData={this.state}
>
</FlatList>
</View>
<View style={styles.footerBtn}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Main', { itemId: undefined })}>
<View style={styles.btnSelect}>
<Text style={styles.txtBtn}>Cancel</Text>
</View>
</TouchableOpacity>
{this.state.btnDisabled === true ? this.MerchSelected('Sim') : this.MerchSelected('Nao')}
</View>
</View >
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f2f2f4',
alignItems: 'center',
},
searchBar: {
flex: 1,
top: '5%',
width: '90%',
backgroundColor: 'rgba(242, 242, 244,0.5)'
},
merchantsList: {
flex: 6,
width: '95%',
},
footerBtn: {
flex: 1,
width: '100%',
},
listItem: {
flexDirection: 'row',
marginTop: 5,
},
notSelected: {
backgroundColor: '#f2f2f4'
},
listItemSlc: {
backgroundColor: '#48D1CC',
},
btnSelect: {
justifyContent: 'center',
width: '95%',
borderRadius: 5,
borderColor: '#00CED1',
borderStyle: 'solid',
borderWidth: 2,
height: 40,
marginTop: 5,
marginLeft: 8,
},
btnDsb: {
justifyContent: 'center',
width: '95%',
borderRadius: 5,
backgroundColor: 'gray',
height: 40,
marginTop: 5,
marginLeft: 8,
},
txtBtn: {
textAlign: 'center',
color: '#00CED1',
fontSize: 20,
},
})
import React, { Component } from 'react';
import { StyleSheet, Text, View, Image, TouchableOpacity, FlatList, Linking, ActivityIndicator } from 'react-native';
import { Searchbar } from 'react-native-paper';
export default class Merchants extends Component {
constructor() {
super()
this.state = {
search: '',
loading: false,
merchantObj: [],
btnDisabled: true,
itemId: null,
imgLink: null,
listClicked: false,
itemindex:"",
}
this.arrayholder = [];
}
componentDidMount() {
const merchantUrl = 'http://165.227.43.115:8080/merchant/merchant'
fetch(merchantUrl)
.then(response => response.json())
.then(data => {
//var l_Data = [];
//for (var l_index = 0; l_index < data.length; l_index++)
//{
// l_Data[l_index] = {
// }
//}
this.setState({ merchantObj: data, loading: false },
function () {
this.arrayholder = data;
})
})
.catch(error => {
console.log(error)
});
}
search = text => {
console.log(text);
};
clear = () => {
this.search.clear();
};
SearchFilterFunction(text) {
//passing the inserted text in textinput
const newData = this.arrayholder.filter(function (item) {
//applying filter for the inserted text in search bar
const itemData = item.name ? item.name.toUpperCase() : ''.toUpperCase();
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
this.setState({
//setting the filtered newData on datasource
//After setting the data it will automatically re-render the view
merchantObj: newData,
search: text,
});
}
FlatListItemSeparator = () => {
return (
<View
style={{
height: 1,
width: "95%",
justifyContent: 'center',
backgroundColor: "#DCDCDC",
}}
/>
);
}
MerchSelected = (selectedId) => {
if (this.state.btnDisabled === true) {
return (
<View style={styles.btnDsb}>
<Text style={styles.txtBtn}>Select</Text>
</View>
)
} else {
return (
<TouchableOpacity onPress={(item) => this.props.navigation.navigate('Main', { itemId: this.state.itemId, itemImg: this.state.imgLink })}>
<View style={styles.btnSelect}>
<Text style={styles.txtBtn}>Select</Text>
</View>
</TouchableOpacity>
)
}
}
PressedItem = (itemId, itemImg) => {
console.log(itemId)
this.setState({ itemId: itemId, btnDisabled: false, imgLink: itemImg })
}
renderItem = ({ item }) => {
return (
<TouchableOpacity onPress={() => { this.PressedItem(item.id, item.image), this.setState({ itemindex: item.id }) }} >
<View style={this.state.itemindex == item.id ? styles.SelectedlistItem : styles.listItem} >
<Image
style={{ width: 80, height: 80 }}
source={{ uri: `${item.image}` }} />
<View style={{ flexDirection: 'column', marginLeft: 2 }}>
< Text style={{ fontWeight: 'bold', fontSize: 20 }} > {item.name} </Text>
{item.shoppingOption == 'STORE' ? <Text>Store</Text> : <Text>In-Store & Online</Text>}
<Text>${item.minAmount} - ${item.maxAmount}</Text>
<Text style={{ color: '#00CED1' }}
onPress={() => Linking.openURL(`${item.website}`)}>
view website
</Text>
</View>
</View>
</TouchableOpacity>
)
}
render() {
if (this.state.loading) {
return (
<View>
<Text>Loading...</Text>
</View>
);
}
return (
<View style={styles.container} >
<View style={styles.searchBar}>
<Searchbar
round
placeholder="Search"
onChangeText={text => this.SearchFilterFunction(text)}
onClear={text => this.SearchFilterFunction('')}
value={this.state.search}
/>
</View>
<View style={styles.merchantsList}>
<FlatList
data={this.state.merchantObj}
renderItem={this.renderItem}
ItemSeparatorComponent={this.FlatListItemSeparator}
keyExtractor={item => item.id.toString()}
extraData={this.state}
/>
</View>
<View style={styles.footerBtn}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Main', { itemId: undefined })}>
<View style={styles.btnSelect}>
<Text style={styles.txtBtn}>Cancel</Text>
</View>
</TouchableOpacity>
{this.state.btnDisabled === true ? this.MerchSelected('Sim') : this.MerchSelected('Nao')}
</View>
</View >
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f2f2f4',
alignItems: 'center',
},
searchBar: {
flex: 1,
top: '5%',
width: '90%',
backgroundColor: 'rgba(242, 242, 244,0.5)'
},
merchantsList: {
flex: 6,
width: '95%',
},
footerBtn: {
flex: 1,
width: '100%',
},
listItem: {
flexDirection: 'row',
marginTop: 5,
},
SelectedlistItem: {
flexDirection: 'row',
marginTop: 5,
backgroundColor:"grey",
},
btnSelect: {
justifyContent: 'center',
width: '95%',
borderRadius: 5,
borderColor: '#00CED1',
borderStyle: 'solid',
borderWidth: 2,
height: 40,
marginTop: 5,
marginLeft: 8,
},
btnDsb: {
justifyContent: 'center',
width: '95%',
borderRadius: 5,
backgroundColor: 'gray',
height: 40,
marginTop: 5,
marginLeft: 8,
},
txtBtn: {
textAlign: 'center',
color: '#00CED1',
fontSize: 20,
},
})
above is code that's you want and the screenshot is here
Since you keep track of the selected itemId, you can simply override the style of selected item as below.
<TouchableOpacity onPress={() => this.PressedItem(item.id, item.image)} >
{/* Suppeose you want to change the background color of selected item as 'red' */}
<View style={item.id !== this.state.itemId ? styles.listItem : [styles.listItem, { backgroundColor: 'red' }]}>
...
</View>
</TouchableOpacity>
But you need to add extraData property in FlatList for telling the list to re-render.
extraData={this.state.itemId}
Hope this helps you. Feel free for doubts.

How to update data in first component when added data in another component

I have two components with realm database one is for listing and other is for adding data. But my problem is that i can't update list when data is adding into second component. I have tried App state listener also but it's not triggering when user come at first screen.
This is list component
import React, { Component } from "react";
import AppScreen from "../AppScreen.js";
import realm from "../databases/RealmController.js";
import colors from "../Ui/colors.js";
import Swipeout from "react-native-swipeout";
import { Icon } from "react-native-vector-icons";
import { NavigationActions } from "react-navigation";
import Dash from "react-native-dash";
import AppStateListener from "react-native-appstate-listener";
import {
AppState,
AppRegistry,
StyleSheet,
Text,
Image,
Button,
View,
FlatList,
TouchableHighlight,
TouchableOpacity,
Alert,
StatusBar,
TextInput
} from "react-native";
type Props = {};
export default class ReminderList extends Component<Props> {
state = {
data: [],
loading: true,
refresh: false,
appState: AppState.currentState
};
static navigationOptions = {
header: null,
title: " List"
};
handleActive() {
console.warn("The application is now active!");
}
handleBackground() {
console.warn("The application is now in the background!");
}
handleInactive() {
console.warn("The application is now inactive!");
}
componentDidMount() {
//this.fetchData();
AppState.addEventListener("change", this.handleAppStateChange);
}
componentWillUnmount() {
AppState.removeEventListener("change", this.handleAppStateChange);
}
gotoAddReminder = () => {
// handle navigation
this.props.screenProps.rootNavigation.navigate("addReminder");
};
handleAppStateChange = nextAppState => {
if (nextAppState === "active") {
this.setState({ data: null });
this.fetchData();
this.setState({ refresh: true });
// console.warn("hello i active");
//this.flatList.scrollToIndex({ animated: true, index: 0 });
}
else {
this.setState({ refresh: false });
// console.warn("hello i inactive");
}
this.setState({ appState: nextAppState });
};
fetchData() {
let reminderList = realm.objects("Reminder");
this.setState({ data: reminderList });
}
renderClientRow(item) {
return (
<TouchableHighlight underlayColor="rgba(192,192,192,1,0.6)">
<View style={styles.cardView}>
<View style={styles.dateView}>
<Text style={styles.dateText}>18</Text>
<Text style={styles.monthText}>Jan</Text>
</View>
<View
style={{
width: 1,
backgroundColor: colors.darkGray,
marginLeft: 15,
marginRight: 20
}}
/>
<View style={{ flexDirection: "row", marginTop: 15, width: "100%" }}>
<View style={{ flexDirection: "column" }}>
<Text style={styles.titleText}>{item.name}</Text>
<Text style={(styles.item, { marginTop: 5 })}>location</Text>
<Dash
style={{
width: 300,
marginTop: 10,
height: 1,
marginRight: 15
}}
/>
<View
style={{
flex: 1,
flexDirection: "row",
marginTop: 5,
marginBottom: 15
}}
>
<Image
style={{
width: 15,
height: 15,
marginTop: 5,
marginRight: 10
}}
source={require("../Image/ic_date.png")}
/>
<Text style={styles.item}>0.40 pm</Text>
</View>
</View>
</View>
</View>
</TouchableHighlight>
);
}
render() {
return (
<View style={styles.container}>
<AppStateListener
onActive={this.handleActive}
onBackground={this.handleBackground}
onInactive={this.handleInactive}
/>
<FlatList
ref={(c) => { this.flatList = c }}
data={this.state.data}
extraData={this.state.refresh}
renderItem={({ item }) => this.renderClientRow(item)}
keyExtractor={item => item.id}
/>
<TouchableOpacity
activeOpacity={0.5}
onPress={() => {
this.gotoAddReminder();
}}
style={styles.TouchableOpacityStyle}
>
<Image
source={{
uri:
"https://reactnativecode.com/wp-content/uploads/2017/11/Floating_Button.png"
}}
style={styles.FloatingButtonStyle}
/>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 0
},
MainContainer: {
justifyContent: "center",
flex: 1,
margin: 10
},
TouchableOpacityStyle: {
position: "absolute",
width: 50,
height: 50,
alignItems: "center",
justifyContent: "center",
right: 30,
bottom: 30
},
FloatingButtonStyle: {
resizeMode: "contain",
width: 50,
height: 50
},
cardView: {
backgroundColor: "#fff",
borderWidth: 0.5,
paddingLeft: 15,
paddingRight: 10,
marginLeft: 10,
marginTop: 10,
marginRight: 10,
borderRadius: 5,
flexDirection: "row"
},
item: {
fontSize: 16,
color: colors.darkGray
},
itemRight: {
fontSize: 18,
textAlign: "right"
},
titleText: {
fontSize: 20,
color: "black",
fontWeight: "400"
},
dateText: {
fontSize: 32,
color: colors.appColor,
fontWeight: "500"
},
monthText: {
fontSize: 22,
color: colors.appColor,
fontWeight: "500"
},
dateView: {
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
marginLeft: 15,
marginRight: 15,
marginTop: 15,
marginBottom: 15
},
rightText: {
fontSize: 22,
color: "black",
textAlign: "right",
fontWeight: "bold"
},
myStarStyle: {
color: "yellow",
backgroundColor: "transparent",
textShadowColor: "black",
textShadowOffset: { width: 1, height: 1 },
textShadowRadius: 2
},
myEmptyStarStyle: {
color: "white"
}
});
This is AddData component
import React, { Component } from "react";
import realm from "../databases/RealmController.js";
import styles from "../Ui/AddClientStyles.js";
import { TextInputLayout } from "rn-textinputlayout";
import DatePicker from "react-native-datepicker";
import {
AppRegistry,
StyleSheet,
Text,
TouchableHighlight,
Button,
View,
ScrollView,
Image,
Alert,
StatusBar,
TextInput
} from "react-native";
const EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s#"]+(\.[^<>()\[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
type Props = {};
export default class AddReminder extends Component<Props> {
state = {
to: "",
from: "",
name: "",
note: "",
location: ""
};
handlePress = async () => {
var Id = realm.objects("Reminder").length + 1;
realm.write(() => {
realm.create("Reminder", {
id: Id,
name: this.state.name,
note: this.state.note,
location: this.state.location,
to: this.state.to,
from: this.state.from
});
});
this.props.navigation.goBack();
};
render() {
return (
<ScrollView style={styles.container}>
<View style={styles.container}>
<View style={styles.profileContainer} />
<View style={styles.bottomContainer}>
<Text style={[styles.titleText, styles.titleStyle]}>
Basic Information
</Text>
<TextInputLayout style={{ marginTop: 0 }}>
<TextInput
style={styles.textInput}
placeholder={"Reminder Title"}
onChangeText={text => this.setState({ name: text })}
/>
</TextInputLayout>
<TextInputLayout style={styles.inputLayout}>
<TextInput
style={styles.textInput}
placeholder={"Note"}
onChangeText={text => this.setState({ note: text })}
/>
</TextInputLayout>
<TextInputLayout style={styles.inputLayout}>
<TextInput
style={styles.textInput}
placeholder={"Location"}
onChangeText={text => this.setState({ location: text })}
/>
</TextInputLayout>
<Text style={[styles.titleText, styles.titleStyle]}>
Date & Time
</Text>
<View style={styles.dateToContainer}>
<View style={{ flexDirection: "column", width: "30%" }}>
<Text style={styles.textInput}>From</Text>
</View>
<View styles={{ flexDirection: "column", width: "70%" }}>
<DatePicker
style={{ width: 200 }}
date={this.state.from}
mode="datetime"
format="YYYY-MM-DD HH:mm"
confirmBtnText="Confirm"
cancelBtnText="Cancel"
customStyles={{
dateIcon: {
position: "absolute",
left: 0,
top: 4,
marginLeft: 0
},
dateInput: {
marginLeft: 36
}
}}
minuteInterval={10}
onDateChange={datetime => {
this.setState({ from: datetime });
}}
/>
</View>
</View>
<View style={styles.dateContainer}>
<View style={{ flexDirection: "column", width: "30%" }}>
<Text style={styles.textInput}>To</Text>
</View>
<View styles={{ flexDirection: "column", width: "70%" }}>
<DatePicker
style={{ width: 200 }}
date={this.state.to}
mode="datetime"
format="YYYY-MM-DD HH:mm"
confirmBtnText="Confirm"
cancelBtnText="Cancel"
customStyles={{
dateIcon: {
position: "absolute",
left: 0,
top: 4,
marginLeft: 0
},
dateInput: {
marginLeft: 36
}
}}
minuteInterval={10}
onDateChange={datetime => {
this.setState({ to: datetime });
}}
/>
</View>
</View>
<TouchableHighlight
style={styles.btnStyle}
onPress={() => {
this.handlePress();
}}
underlayColor="#fff"
>
<Text style={styles.btnText}>Add Reminder</Text>
</TouchableHighlight>
<TouchableHighlight
style={{marginTop:20}}>
<Text/>
</TouchableHighlight>
</View>
</View>
</ScrollView>
);
}
}
When u use this.props.navigation.goBack(); those components not render again or not call any method that component so can use this.props.navigation.navigate('your_route_path');

conditionality render headerRight - React Native

I have to render headerRight conditionally in navigation options.
Right now
static navigationOptions = ({ navigation }) => ({
title: i18N.t('atmbranchpickHeader'),
headerRight: (
<TouchableHighlight
underlayColor="#E22F39"
onPress={() => {
navigation.navigate("home");
}}
>
<Image
style={{ marginRight: 20 }}
source={require('../../resources/toolbar/home_white.png')}
/>
</TouchableHighlight>
),
headerTintColor: "white",
headerStyle: {
backgroundColor: "#E22F39"
// top: 30
}
});
My Component
import React, { Component } from "react";
import {
View,
TextInput,
Text,
TouchableOpacity,
TouchableHighlight,
StyleSheet,
AsyncStorage,
BackHandler,
Image,
FlatList,
Dimensions,
TouchableWithoutFeedback
} from "react-native";
import i18n from "../../i18n/i18n.js";
import { colors } from "../../constants/colors.js";
import Storage from "../../utils/AsyncStorage.js";
class AtmBranchTypeSelect extends Component {
// Render callBack
constructor(props) {
super(props);
this.state = {
data: [
],
stBool: false,
}
}
async componentWillMount() {
BackHandler.addEventListener('hardwareBackPress', () => this.props.navigation.goBack());
}
componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', () => this.props.navigation.goBack());
}
static navigationOptions = ({ navigation }) => ({
title: i18n.t('atmbranchpickHeader'),
headerRight: (
<TouchableHighlight onPress={() => {
navigation.navigate('home');
}}>
<Image style={{ marginRight: 20 }} source={require('../../resources/toolbar/home_white.png')} />
</TouchableHighlight>),
headerTintColor: 'white',
headerStyle: {
backgroundColor: colors.themeColor,
// top: 30
}
});
_renderList = ({ item }) => {
return (
<TouchableWithoutFeedback onPress={(event) => this._selectedItem(item.key)}>
<View style={styles.listRowContainer}>
<View style={styles.listinside1Container}>
<Image style={styles.listImage} source={item.icon} />
<View style={styles.listContainer} onPress={(event) => this._selectedItem(item.text)} >
<Text style={styles.listHeader} >{item.header}</Text>
<Text style={styles.listValue} >{item.value}</Text>
</View>
</View>
<Image style={styles.listimgArrow} source={require('../../resources/toolbar/chevron_right_grey.png')} />
</View>
</TouchableWithoutFeedback>
);
}
// Render callBack
render() {
return (
<View style={styles.mainWrapper} >
<FlatList data={this.state.data} renderItem={this._renderList} />
</View>
);
}
}
const styles = StyleSheet.create({
mainWrapper: {
flex: 1,
height: Dimensions.get('window').height,
width: Dimensions.get('window').width,
flexDirection: 'column',
justifyContent: 'flex-start'
},
listRowContainer: {
flexDirection: 'row',
marginTop: 10,
height: 80,
backgroundColor: '#FFFFFF',
justifyContent: 'space-between',
borderBottomWidth: 1,
borderColor: 'lightgray'
},
listinside1Container: {
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'center'
},
listContainer: {
alignItems: 'flex-start',
justifyContent: 'center',
flexDirection: 'column',
backgroundColor: '#FFFFFF',
// borderBottomWidth: 1,
// borderColor: 'lightgray'
},
listHeader: {
color: 'black',
fontFamily: 'Roboto-Medium',
marginLeft: 10,
fontSize: 18,
},
listValue: {
fontFamily: 'Roboto-Regular',
marginTop: 4,
color: 'black',
marginLeft: 10,
fontSize: 14,
},
listImage: {
alignSelf: 'center',
height: 25,
width: 25,
margin: 10
},
listimgArrow: {
// flex: 1,
// flexDirection:'row',
alignSelf: 'center',
height: 25,
width: 25,
margin: 10
},
listVal: {
borderWidth: 1,
borderRadius: 10,
color: 'darkgreen',
borderColor: 'white',
backgroundColor: 'white',
fontWeight: 'bold'
},
});
export default AtmBranchTypeSelect;
From the code I have, headerRight will be displayed in all scenarios. consider I have a scenario like based on state value I have to enable/disable headerRight Button .
for example this.state.stBool? headerRight:(.....) : null
I have to render in this way.Please guide me to achieve this.
You could nest the navigation options inside the render and toggle it based on the state value. Haven't tested and not positively on performace. Hope it helps.
import React, { Component } from "react";
import {
View,
TextInput,
Text,
TouchableOpacity,
TouchableHighlight,
StyleSheet,
AsyncStorage,
BackHandler,
Image,
FlatList,
Dimensions,
TouchableWithoutFeedback
} from "react-native";
import i18n from "../../i18n/i18n.js";
import { colors } from "../../constants/colors.js";
import Storage from "../../utils/AsyncStorage.js";
class AtmBranchTypeSelect extends Component {
// Render callBack
constructor(props) {
super(props);
this.state = {
data: [],
stBool: false
};
}
async componentWillMount() {
BackHandler.addEventListener("hardwareBackPress", () =>
this.props.navigation.goBack()
);
}
componentWillUnmount() {
BackHandler.removeEventListener("hardwareBackPress", () =>
this.props.navigation.goBack()
);
}
_renderList = ({ item }) => {
return (
<TouchableWithoutFeedback onPress={event => this._selectedItem(item.key)}>
<View style={styles.listRowContainer}>
<View style={styles.listinside1Container}>
<Image style={styles.listImage} source={item.icon} />
<View
style={styles.listContainer}
onPress={event => this._selectedItem(item.text)}
>
<Text style={styles.listHeader}>{item.header}</Text>
<Text style={styles.listValue}>{item.value}</Text>
</View>
</View>
<Image
style={styles.listimgArrow}
source={require("../../resources/toolbar/chevron_right_grey.png")}
/>
</View>
</TouchableWithoutFeedback>
);
};
// Render callBack
render() {
const { stBool } = this.state;
const navigationOptions = ({ navigation }) => ({
title: i18n.t("atmbranchpickHeader"),
headerRight: stBool ? (
<TouchableHighlight
onPress={() => {
navigation.navigate("home");
}}
>
<Image
style={{ marginRight: 20 }}
source={require("../../resources/toolbar/home_white.png")}
/>
</TouchableHighlight>
) : null,
headerTintColor: "white",
headerStyle: {
backgroundColor: colors.themeColor
// top: 30
}
});
return (
<View style={styles.mainWrapper}>
<FlatList data={this.state.data} renderItem={this._renderList} />
</View>
);
}
}

Resources