React Native onPress active state change image source on Carousel - react-native

Trying to change image of a button on my carousel elements, currently it (below code) changes all the images when I click any of them. I'd like change that only current carousel's image. Any ideas? Thanks
class CarouselImages extends React.Component {
constructor(props) {
super(props);
this.state = {
myImagesArray: [
{
key: 1,
title: 'Category'
},
{
key: 2,
title: 'Category'
},
{
key: 3,
title: 'Category'
}
],
icon_active: false,
}
activateCarouselButton = a => {
const newState = Object.assign(
{},
{
icon_active: false,
},
{ [a]: true },
)
this.setState(newState);
}
}
render = () => {
const { icon_active } = this.state;
var myCarousel = this.state.myImagesArray.map(function (index) {
return (
<View key={index}>
<TouchableHighlight onPress={() => activateCarouselButton('icon_active')} >
<Image
source={icon_active ? require('../Image/active#2x.png') : require('../Image/disabled#2x.png')} />
</TouchableHighlight>
</View>
);
});
return (
<View>
<Carousel
style={{ backgroundColor: '#fff' }}>
{myCarousel}
</Carousel>
</View>
)
}
}

You need to hold key of the icon in the icon_active state, not a boolean. This gives you a hunch on how to do it:
render() {
const { icon_active } = this.state;
return (
this.state.myImagesArray.map((image) => {
return (
<View key={image.key}>
<TouchableHighlight onPress={() => activateCarouselButton(image.key)}>
<Image source={icon_active === image.key ? require('../Image/active#2x.png') : require('../Image/disabled#2x.png')} />
</TouchableHighlight>
</View>
)
})
)
}

<Image source={this.props.secureTextEntry ?
require('../../assets/images/signup/Showpassword.png') :
require('../../assets/images/signup/Hidepassword.png')} />

Related

improving elements styles to make a full screen scan

I will need a helping hand to edit this page. i have all the elements but i need help styling.
I would like to have the camera (the image you see is the typical emulator camera, that's why it makes an image) in full screen and from above at the top, the message in red and the 'autocomplete.
If you want, to explain better, I would like to respect the image below: autocomplete at the top left above the camera in full screen.
would it be possible for you to help me, I'm getting a little confused. I tried to do a snack but failed. I will add it later if i can.
const autocompletes = [...Array(10).keys()];
const apiUrl = "https://5b927fd14c818e001456e967.mockapi.io/branches";
class Tickets extends Component {
constructor(props) {
super(props);
this.state = {
Press: false,
hasCameraPermission: null,
reference: '',
lastScannedUrl:null,
displayArray: []
};
}
initListData = async () => {
let list = await getProductByRef(1);
if (list) {
this.setState({
displayArray: list,
reference: list.reference
});
}
// console.log('reference dans initListData =', list.reference)
};
async UNSAFE_componentWillMount() {
this.initListData();
// console.log('reference dans le state =', this.state.reference)
};
componentDidMount() {
this.getPermissionsAsync();
}
getPermissionsAsync = async () => {
const { status } = await Permissions.askAsync(Permissions.CAMERA);
this.setState({ hasCameraPermission: status === "granted" });
};
_onPress_Scan = () => {
this.setState({
Press: true
});
}
handleBarCodeScanned = ({ type, data }) => {
this.setState({ Press: false, scanned: true, reference: data });
this.props.navigation.navigate('ProductDetails', {reference : parseInt(this.state.state.reference)})
};
renderBarcodeReader = () => {
const { hasCameraPermission, scanned } = this.state;
if (hasCameraPermission === null) {
return <Text>{i18n.t("scan.request")}</Text>;
}
if (hasCameraPermission === false) {
return <Text>{i18n.t("scan.noaccess")}</Text>;
}
return (
<View
style={{
flex: 1,
...StyleSheet.absoluteFillObject
}}
>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : this.handleBarCodeScanned}
style={{ flex:1, height:'100%', ...StyleSheet.absoluteFillObject}}
/>
{scanned && (
<Button
title={"Tap to Scan Again"}
onPress={() => this.setState({ scanned: false })}
/>
)}
</View>
);
}
handleSelectItem(item, index) {
const {onDropdownClose} = this.props;
onDropdownClose();
console.log(item);
}
render() {
const { hasCameraPermission, scanned, Press } = this.state;
let marker = null;
const {scrollToInput, onDropdownClose, onDropdownShow} = this.props;
// console.log('displayArray', this.state.displayArray, 'reference', this.state.displayArray.reference)
return (
<View style={styles.container}>
{Press ? (
<View style={{flex:1}}>
<View style={styles.dropdownContainerStyle}>
<Autocomplete
key={shortid.generate()}
containerStyle={styles.autocompleteContainer}
inputStyle={{ borderWidth: 1, borderColor: '#F78400'}}
placeholder={i18n.t("tickets.warning")}
pickerStyle={styles.autocompletePicker}
scrollStyle={styles.autocompleteScroll}
scrollToInput={ev => scrollToInput(ev)}
handleSelectItem={(item, id) => this.handleSelectItem(item, id)}
onDropdownClose={() => onDropdownClose()}
onDropdownShow={() => onDropdownShow()}
fetchDataUrl={apiUrl}
minimumCharactersCount={2}
highlightText
valueExtractor={item => item.name}
rightContent
rightTextExtractor={item => item.properties}
/>
</View>
{this.renderBarcodeReader()}
</View>
) : (
<View style={{flex:1, justifyContent:'center', alignItems:'center'}}>
<Button
color="#F78400"
title={i18n.t("scan.scan")}
onPress={this._onPress_Scan}>
</Button>
</View>
)}
</View>
);
}
}
export default Tickets;
This gives me (after pressing the button) :
SNACK CODE TEST
I notice You are using a component from Expo called BarCodeScanner
There's a github issue open about the fact that this component is not possible to be styled for full screen: https://github.com/expo/expo/issues/5212
However one user proposes a good solution: replace BarCodeScanner with Camera and use barcodescannersettings
Here's a link for the answer on the gitHub issue: https://github.com/expo/expo/issues/5212#issuecomment-653478266
Your code should look something like:
renderBarcodeReader = () => {
const { hasCameraPermission, scanned } = this.state;
[ ... ] // the rest of your code here
return (
<View
style={{
flex: 1,
...StyleSheet.absoluteFillObject
}}
>
<Camera
onBarCodeScanned={scanned ? undefined : this.handleBarCodeScanned}
style={{ flex:1}}
barCodeScannerSettings={{
barCodeTypes: [BarCodeScanner.Constants.BarCodeType.qr],
}}
/>
</View>
);
}

Understand error : Cannot update a component from inside the function body of a different component

I have this error and I don't understand where it came from.
I'm trying to set up a screen where I scan products and when it's done, I redirect to another page.
Could you help me identify the problem and why it behaves like this?
the error is :
Warning: Cannot update a component from inside the function body of a
different component.
My Code :
class Scan extends Component {
constructor(props) {
super(props);
this.state = {
Press: false,
hasCameraPermission: null,
reference: '',
displayArray: []
};
}
initListData = async () => {
let list = await getProducts(1);
if (list) {
this.setState({
displayArray: list,
});
}
};
async UNSAFE_componentWillMount() {
this.initListData();
if (parseInt(this.state.reference) > 0) {
let product_data = await getProductByRef(this.state.reference);
console.log(this.state.reference);
if (product_data && product_data.reference_id && parseInt(product_data.reference_id) > 0) {
this.props.navigation.navigate('ProductDetails', {reference : parseInt(this.state.displayArray.reference)})
} else {
this.props.navigation.goBack();
}
} else {
this.props.navigation.goBack();
}
};
componentDidMount() {
this.getPermissionsAsync();
}
getPermissionsAsync = async () => {
const { status } = await Permissions.askAsync(Permissions.CAMERA);
this.setState({ hasCameraPermission: status === "granted" });
};
_onPress_Scan = () => {
this.setState({
Press: true
});
}
handleBarCodeScanned = ({ type, data }) => {
this.setState({ Press: false, scanned: true, lastScannedUrl: data });
};
renderBarcodeReader = () => {
const { hasCameraPermission, scanned } = this.state;
if (hasCameraPermission === null) {
return <Text>{i18n.t("scan.request")}</Text>;
}
if (hasCameraPermission === false) {
return <Text>{i18n.t("scan.noaccess")}</Text>;
}
return (
<View
style={{
flex: 1,
flexDirection: "column",
justifyContent: "flex-end",
}}
>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : this.handleBarCodeScanned}
style={{ flex:1, ...StyleSheet.absoluteFillObject}}
/>
{scanned && (
<Button
title={"Tap to Scan Again"}
onPress={() => this.setState({ scanned: false })}
/>
)}
<Button
color="#F78400"
title= {i18n.t("scan.details")}
onPress={() => this.props.navigation.navigate('ProductDetails', {reference : parseInt(this.state.displayArray.reference)})}>{i18n.t("scan.details")}
</Button>
</View>
);
}
render() {
const { hasCameraPermission, scanned, Press } = this.state;
let marker = null;
console.log('displayArray', this.state.displayArray, 'reference', this.state.displayArray.reference)
return (
<View style={{flex:1}}>
<KeyboardAvoidingView behavior="padding" enabled style={{flex:1}}>
<ScrollView contentContainerStyle={{flexGrow: 1}} >
{Press ? (
<View style={{flex:1}}>
{this.renderBarcodeReader()}
</View>
) : (
<View style={{flex:1, justifyContent:'center', alignItems:'center'}}>
<TouchableOpacity
onPress={this._onPress_Scan}
activeOpacity={3}
>
<Text style={styles.viewDetails}>Scan BarCode</Text>
</TouchableOpacity>
</View>
)}
</ScrollView>
</KeyboardAvoidingView>
</View>
);
}
}
export default Scan;

How to get the index value of FlatList in the header using React-native

I need to get the index value of the FlatList used in header of a React native component.
Below is the code I used.I need the parameter rowItem in onPressAction function which is returned as undefined
constructor(props) {
super(props);
this.state = {
selectedItem: '',
headerData: [
{ image: require('common/assets/images/headers/homeicon.png') },
{ image: require('common/assets/images/headers/CustomerDetails2.png') }
]
}
}
componentDidMount() {
// Event Listener for orientation changes
Dimensions.addEventListener('change', () => {
this.setState({
orientation: isPortrait() ? 'portrait' : 'landscape'
});
});
this.props.navigation.setParams({
headerData: this.state.headerData,
selectedItem: this.state.selectedItem,
onPressAction: (item) => this.onPressAction()
});
}
onPressAction = (rowItem) => {
alert(rowItem);
}
static navigationOptions = ({ navigation }) => {
return {
headerTransparent: true,
headerLeft: (
<View style={{ flex: 1, flexDirection: 'row' }} >
<FlatList
horizontal={true}
extraData={navigation.getParam('selectedItem')}
data={navigation.getParam('headerData')}
renderItem={({ item, index }) => (
<TouchableOpacity onPress={navigation.getParam('onPressAction')} >
<Image style={styles.centerIcon} resizeMode='contain' source={item.image}></Image>
</TouchableOpacity>
)}
keyExtractor={(item, index) => index.toString()}
/>
</View >
),
headerTintColor: 'transparent',
};
};
Could anyone please help me
Insert ID into headerData and use it as index value.
headerData: [
{ id: 0 , image: require('common/assets/images/headers/homeicon.png') },
{ id: 1 , image: require('common/assets/images/headers/CustomerDetails2.png') }
]
...
}
renderItem={({ item, index }) => (
<TouchableOpacity onPress={() => alert(navigation.getParam('onPressAction'))} >
<Image style={styles.centerIcon} resizeMode='contain' source={item.image}></Image>
</TouchableOpacity>
)}

React Native Pass Index to Props

I have a modal that contain icons and description and status, and i want to pass the icons and descriptions from index to the modal,I already pass the status. is there anyway to do that? sorry i'm still new to react native and thanks in advance
this is my index.js
export const img =
{
itemStatus: {
"Open": { name: 'open-book', type: 'entypo', color: '#ffb732', desc:'New Attribut, New Attention'},
"Approved": { name: 'checklist', type: 'octicon', color: '#3CB371', desc:'Approved by SPV/MNG' },
"Escalated": { name: 'mail-forward', type: 'font-awesome', color: '#ffb732', desc:'Escalated to SPV/MNG' },
"Deliver Partial": { name: 'arrange-send-to-back', type: 'material-community', color: '#8B4513', desc:'Some items in a DO have not arrived/was faulty' },
};
and this is my container
class MyRequest extends React.Component {
constructor() {
super();
this.state = {
currentStatus: null,
refreshing: false,
fetchStatus: null
};
handleShowModal = (status) =>{
this.setState({
currentStatus: status,
});
}
handleDismissModal = () =>{
this.setState({currentStatus: null});
}
<View style={[styles.panelContainer, status === 'success' ? {} : { backgroundColor: color.white }]}>
<FlatList
showsVerticalScrollIndicator={false}
progressViewOffset={-10}
refreshing={this.state.refreshing}
onRefresh={this.onRefresh.bind(this)}
onMomentumScrollEnd={(event) => event.nativeEvent.contentOffset.y === 0 ? this.onRefresh() : null}
data={content}
renderItem={({ item }) => item}
keyExtractor={(item, key) => key.toString()}
/>
</View>
<IconModal visible={this.state.modalVisible} close={this.handleDismissModal} icon={} status={this.state.currentStatus} desc={} />
}
and this is my modal
const IconModal = (props) => {
return(
<Modal
isVisible={props.visible}
onBackdropPress={props.close}
>
<View style={styles.dialogBox}>
<View style={styles.icon}>
<Icon>{props.icon}</Icon>
</View>
<View style={styles.text}>
<Text style={styles.status}>{props.status}</Text>
<Text>{props.desc}</Text>
</View>
<TouchableOpacity onPress={props.close}>
<View>
<Text style={styles.buttonText}>GOT IT</Text>
</View>
</TouchableOpacity>
</View>
</Modal>
)
}
It's a bit unclear how you plan on mapping against img.itemStatus index but you can just reference the object you want as such.
import img from '....path_to_index.js'
...
// const currentItemStatus = img.itemStatus.Open
// OR
const itemStatus = 'Open' // Or 'Approved', 'Escalated', 'Deliver Partial'
const currentItemStatus = img.itemStatus[itemStatus]
...
<IconModal
visible={this.state.modalVisible}
close={this.handleDismissModal}
icon={currentItemStatus.name} // Passing name
status={this.state.currentStatus}
desc={currentItemStatus.desc} // Passing desc
/>
...
Hope this was helpful

change custom radio button image onclick

I'm trying to create a button that can change the image when it is clicked, I've tried with changing its opacity now I'm trying to change the image. Here's what I've done for the custom button
const styles = StyleSheet.create({
container: {
marginVertical: normalize(5),
opacity: 0.5
},
activeButton: {
opacity: 1
}
});
export default class RadioButton extends Component {
constructor(props) {
super(props);
this.state = {
selected: this.props.currentSelection === this.props.value,
}
}
componentDidUpdate(prevProps) {
if (this.props.currentSelection !== prevProps.currentSelection) {
this.setState({ selected: this.props.currentSelection === this.props.value });
}
}
render() {
let activeButton = this.props.activeStyle ? this.props.activeStyle : styles.activeButton;
return (
<View style={[styles.container, this.props.containerStyle, this.state.selected ? activeButton : null]}>
<TouchableOpacity onPress={() => {
this.setState({ selected: !this.state.selected });
this.props.onPress();
}}>
{
this.props.element ?
this.props.element :
<Text> {this.props.value} </Text>
}
</TouchableOpacity>
</View>
);
}
}
It should be like this image
First import both images. one for selected and another for normal state.
import selectedImg from '../images/selected.png';
import normalImg from '../images/normal.png';
and then add below method to your component
btnBackgroundImage() = {
var imgSource = this.state.selected? selectedImg : normalImg;
return (
<Image
style={'put style here'}
source={ imgSource }
/>
);
}
now edit your render method like below
render() {
let activeButton = this.props.activeStyle ? this.props.activeStyle : styles.activeButton;
return (
<View style={[styles.container, this.props.containerStyle, this.state.selected ? activeButton : null]}>
<TouchableOpacity onPress={() => {
this.setState({ selected: !this.state.selected });
this.props.onPress();
}}>
{
this.btnBackgroundImage()
}
</TouchableOpacity>
</View>
);
}