Not able to set active and inactive images in React Native - react-native

I am showing custom tab-bar in my application which is showing at centre of the screen. So, Each time one tab should be active and other tabs will be inactive state.
According to that, I have implemented logic(bool values) and tried to change images, But, It's not working.
My requirement is
I have 4 tabs, suppose if user tap on 1st tab, I have to set active
image to 1st tab then rest of 3 tabs with inactive images according to
those titles (different inactive) images.
Its like for all tabs active and inactive states, each time one tab
only active state.
It's showing undefined and even if and else if conditions executing, But, nothing changing images.
Here is my code
constructor(props) {
super(props);
// this.state = { dataArray: getListData()}
this.state = { selectedTab: 'Value', flagImage:true, flagForTelugu: false, flagForTamil: false, flagForHindi: false, flagForEnglish: false}
}
OnTabItemHandler = (tabItem) => {
this.setState({selectedTab: tabItem,flagImage:this.state.flagImage})
}
renderBottomContent = (item) => {
const {selectedTab, dataArray, flagForTelugu, flagForTamil, flagForHindi, flagForEnglish} = this.state
this.state = { dataArray: getListData()}
if (selectedTab === ‘Telugu’) {
this.flagForTelugu = true
this.flagForTamil = false
this.flagForHindi = false
this.flagForEnglish = false
} else if (selectedTab === ‘Tamil’) {
this.flagForTamil = true
this.flagForTelugu = false
this.flagForHindi = false
this.flagForEnglish = false
} else if (selectedTab === ‘Hindi’) {
this.flagForHindi = true
this.flagForTamil = false
this.flagForTelugu = false
this.flagForEnglish = false
} else if (selectedTab === ‘English’) {
this.flagForEnglish = true
this.flagForTamil = false
this.flagForTelugu = false
this.flagForHindi = false
}
//loading some other text here in bottom
}
render(item) {
const {selectedTab, flagForTelugu, flagForTamil, flagForHindi, flagForEnglish} = this.state;
return (
<View style={styles.container}>
<View style = {styles.tabContainer}>
<TouchableOpacity style={styles.tabIcons} onPress={() => this.OnTabItemHandler(‘Telugu’)}>
<Image
style={styles.tabItemsImages}
source={this.state.flagImage === true ?
teluguActiveImage :
teluguDeActiveImage}
/>
</TouchableOpacity>
<Text style={styles.tabTextItems} onPress={() => this.OnTabItemHandler('Telugu')}>Telugu</Text>
</View>
<View style = {styles.tabContainer}>
<TouchableOpacity style={styles.tabIcons} onPress={() => this.OnTabItemHandler(‘Tamil’)}>
<Image
style={styles.tabItemsImages}
source={this.state.flagImage === true ?
tamilActiveImage :
tamilDeActiveImage}
/>
</TouchableOpacity>
<Text style={styles.tabTextItems} onPress={() => this.OnTabItemHandler('Tamil')}> Tamil </Text>
</View>
<View style = {styles.tabContainer}>
<TouchableOpacity style={styles.tabIcons} onPress={() => this.OnTabItemHandler(‘Hindi’)}>
<Image
style={styles.tabItemsImages}
source={this.state.flagImage === true ?
hindiActiveImage :
hindiDeActiveImage}
/>
</TouchableOpacity>
<Text style={styles.tabTextItems} onPress={() => this.OnTabItemHandler('Hindi')}> Hindi </Text>
</View>
<View style = {styles.tabContainer}>
<TouchableOpacity style={styles.tabIcons} onPress={() => this.OnTabItemHandler(‘English’)}>
<Image
style={styles.tabItemsImages}
source={this.state.flagImage === true ?
englishActiveImage :
englishDeActiveImage}
/>
</TouchableOpacity>
<Text style={styles.tabTextItems} onPress={() => this.OnTabItemHandler('English')}> English </Text>
</View>
</View>
{this.renderBottomContent(item)}
</View>
);
}
Can anyone suggest me, Where I am doing wrong?
And in the method renderBottomContent(), these flagForTelugu,
flagForTamil, flagForHindi, flagForEnglish showing as undefined while
debugging time.

I'm not good to explaining how the code works.
but the idea is you need 1 state called selectedIndex and the rest is you need to check the active image with the selectedIndex is match show the active image
the example code may looks like this:
import React, { Component } from 'react';
import RN from 'react-native';
export default class App extends Component {
constructor(props) {
super(props);
this.state={
selectedIndex:0,
//you can change every urlActive and urlInactive url to your needed image
tabList:[
{label:'tab 1', urlActive:'https://livelovely.com/static/images/full-listing/icon-modal-success%402x.png', urlInactive:'https://icon2.kisspng.com/20180823/ioc/kisspng-traffic-sign-image-traffic-code-no-symbol-inactive-symbol-www-pixshark-com-images-gallerie-5b7e884790b8a3.5710860815350190795928.jpg'},
{label:'tab 2', urlActive:'https://livelovely.com/static/images/full-listing/icon-modal-success%402x.png', urlInactive:'https://icon2.kisspng.com/20180823/ioc/kisspng-traffic-sign-image-traffic-code-no-symbol-inactive-symbol-www-pixshark-com-images-gallerie-5b7e884790b8a3.5710860815350190795928.jpg'},
{label:'tab 3', urlActive:'https://livelovely.com/static/images/full-listing/icon-modal-success%402x.png', urlInactive:'https://icon2.kisspng.com/20180823/ioc/kisspng-traffic-sign-image-traffic-code-no-symbol-inactive-symbol-www-pixshark-com-images-gallerie-5b7e884790b8a3.5710860815350190795928.jpg'},
]
}
}
render() {
console.disableYellowBox = true;
return (
<RN.View style={{flex:1}}>
//creating the tab height
<RN.View style={{flex:0.07, flexDirection:'row'}}>
{
//loop throught the state
this.state.tabList.map((item,index)=>{
return(
//the style just to make it beautiful and easy to debug
<RN.TouchableOpacity style={{flex:1, alignItems:'center', backgroundColor:index==0?'green':index==1?'blue':'yellow'}}
//this onpress to handle of active selected tab
onPress={()=>{this.setState({selectedIndex:index})}}
>
<RN.View>
<RN.Text>{item.label}</RN.Text>
<RN.Image
//here's the magic show off
source={{uri:this.state.selectedIndex==index?item.urlActive:item.urlInactive}}
style={{width:20, height:20, resizeMode:'contain'}}
/>
</RN.View>
</RN.TouchableOpacity>
)
})
}
</RN.View>
</RN.View>
);
}
}
and the result look like :

Related

How to use hooks as image's source in react native?

Im making this menu that when the user clicks at an option, it changes the background image, but i cant use the hook that i created as a parameter to the source of the image. Can someone find where im wrong and how to fix it?
Heres the part of my code referents to the menu and the hooks:
export function Home(){
let imagens = {
vovo: '../assets/vovoJuju.png',
mc: '../assets/mcJuju.png',
pato: '../assets/patoJuju.png',
}
const navigation = useNavigation<any>();
const [showBottomSheet, setShowBottomSheet] = React.useState(false);
const [param, setParam] = useState(1);
const [skin, setSkin] = useState('vovo')
const hide = () => {
setShowBottomSheet(false)
}
function handleAbout(){
navigation.navigate('About');
}
useEffect(() => {
if(param==1){
setSkin('vovo');
}
else if(param==2){
setSkin('mc');
}
else if(param==3){
setSkin('pato');
}
})
return(
<SafeAreaView style={styles.container}>
<TouchableOpacity onPress={handleAbout}>
<Counter />
</TouchableOpacity>
<TouchableOpacity onPress={() => {
setShowBottomSheet(true)
}}
>
<Image source={skin} style={styles.imgvj}/>
</TouchableOpacity>
<BottomSheet show={showBottomSheet} height={290} onOuterClick={hide}>
<Pressable onPress={hide} style={styles.bottomSheetContent}>
<Image source={barrinhaLoja} style={styles.barra}/>
</Pressable>
<View style={styles.conteudoLoja}>
<View style={styles.marginLeft48}>
<TouchableOpacity onPress={() => {
setParam(1);
}}>
<Image source={vovoJuju} style={styles.vovo}/>
<Text style={styles.legendasLoja}>Vovó Juju</Text>
</TouchableOpacity>
</View>
<View>
<TouchableOpacity onPress={() => {
setParam(2);
}}>
<Image source={mcJuju} style={styles.mc}/>
<Text style={styles.legendasLoja}>MC Juju</Text>
</TouchableOpacity>
</View>
<View>
<TouchableOpacity onPress={() => {
setParam(3);
}}>
<Image source={patoJuju} style={styles.pato}/>
<Text style={styles.legendasLoja}>Pato Juju</Text>
</TouchableOpacity>
</View>
</View>
</BottomSheet>
I created the "let imagens", "const param", "const skin" and the "useEffect trying" to make this function. I already tried using the source in different ways such as source={skin} and source={imagens[skin]} but it havent worked.
I'm not certain if this solves your problem, but here's how the first few lines of your component should look like without useEffect:
const imagens = {
vovo: '../assets/vovoJuju.png',
mc: '../assets/mcJuju.png',
pato: '../assets/patoJuju.png',
};
export function Home(){
const navigation = useNavigation<any>();
const [showBottomSheet, setShowBottomSheet] = React.useState(false);
const [param, setParam] = useState(1);
const hide = () => {
setShowBottomSheet(false)
}
function handleAbout(){
navigation.navigate('About');
}
let skin = 'vovo';
switch(param) {
case 1: skin = 'vovo'; break;
case 2: skin = 'mc'; break;
case 3: skin = 'pato'; break;
}
return /* the rest goes here */
}
To reference the actual image, you would use something like {imagens[skin]}.
I moved imagens outside of this function because it never changes, but it doesn't impact anything otherwise.

Switch button in react-native

Hi I have a problem with the switch button in react-native. I'm using it to toggle or not the activation of push notification. The problem is that if I quit the application, the state of the switch is getting back to false, it's not saving the state ? What am I doing wrong ?
Here is my code :
constructor(props) {
super(props)
this.state = {
switchValue:false
}
}
toggleSwitch = (value) => {
this.setState({switchValue: value})
if(this.state.switchValue){
console.log("Unsubscribed")
} else {
console.log("Subscribed")
}
}
render() {
return (
<SafeAreaView>
<ScrollView>
<View style = {styles.view_container}>
<Text style = {styles.titre}>Notifications</Text>
<Text style = {{marginTop:9}}>Permet de recevoir des alertes lorsque de nouvelles vidéos sont disponibles.</Text>
<View style = {{marginTop: 30, justifyContent:"center", alignContent:"center"}}>
<View style = {styles.row}>
<View style = {styles.row_infos}>
<Image source={require('../Images/couleurs/icons8-belier-100.png')} style = {styles.image}/>
<Text style = {{fontWeight:"bold", fontSize:16,lineHeight:16, color:"#7c4dff"}}>Bélier</Text>
</View>
<Switch
onValueChange = {this.toggleSwitchBelier}
value = {this.state.switchValueBelier}
trackColor={{false:'#000000', true:'#7c4dff'}}
/>
</View>
</View>
</View>
</ScrollView>
</SafeAreaView>
)}
When you quit your Application, all saved variables in the state will be "resetted".
If you would like to keep the state of the toggle button, i would recommend you to use the AsyncStorage, provided by expo.
See here:
https://docs.expo.io/versions/v36.0.0/react-native/asyncstorage/
Just set the item when the toggle-function is triggered like this:
import { AsyncStorage } from 'react-native';
AsyncStorage.setItem('buttonToggle', 'true');
And when you start the application again, load the current status from the AsyncStorage:
const value = await AsyncStorage.getItem('buttonToggle');
if (!!value && value === 'true'){
// Do whatever you like
}

How to update useState into TextInput

I have a simple <TextInput> in React Native and i want to print some text when value change. Its working after second character entered, but not, when user press just one char.
I try using functions and even with onChange and take from e.target.value but allways are missing one character at "search" state.
import React, { useState } from 'react';
import { TextInput, View, Text } from 'react-native';
const App = () => {
const [search, setSearch] = useState('');
const [searching, setSearching] = useState(false);
return(
<View>
<TextInput
onChangeText={(value) => {
setSearch(value)
setSearching(search=='' ? false : true)
}}
value = { search }
/>
{
searching ?
(
<Text>Searching</Text>
) : (
<Text>No searching</Text>
)
}
</View>
);
}
export default App
I expect to show "Searching" when TextBox value are not empty.
useState or setState may be asynchronous, so the first time you call setSearch(value), the search state may not be updated yet.
onChangeText={(value) => {
setSearch(value)
setSearching(search == '' ? false : true) // "search" is still previous value
}}
Instead, you can directly use value instead for checking.
onChangeText={(value) => {
setSearch(value)
setSearching(value == '' ? false : true) // value is latest
}}
You need to compare the actual value of the TextInput
Using search=='' ? false : true will check the previous state and won't change
onChangeText={(value) => {
setSearch(value)
setSearching(search=='' ? false : true)
}}
This will check for the changed value.
onChangeText={(value) => {
setSearch(value)
setSearching(value == '' ? false : true) // use value
}}
You need to use value instead of search
Just change this
setSearching(search=='' ? false : true)
to
setSearching(value=='' ? false : true)
After help of both i resolved. This is the code if help to somebody. The idea are a TextInput with a len icon on the left, and when user start to write made the call to Firebase and show a loading icon on the right (spinner).
<Icon
name='search'
size={25}
color={PRIMARY_BACKGROUND_COLOR}
style={styles.searchIcon}
/>
<TextInput
underlineColorAndroid = 'transparent'
style = { styles.textBox }
onChangeText={(value) => { onChangeText(value) }}
value = { search }
placeholder = { i18n.t('Search') }
/>
{
searching ?
(
<TouchableOpacity style = { styles.visibilityBtn }>
<Animatable.View
ref={ref => (this.AnimationRef = ref)}
animation='rotate'
easing='linear'
iterationCount='infinite'
>
<Icon
name='spinner-3'
size={20}
color={PRIMARY_BACKGROUND_COLOR}
/>
</Animatable.View>
</TouchableOpacity>
) : (
<TouchableOpacity onPress={ clearSearch } style = { styles.visibilityBtn }>
<Icon
name='close'
size={20}
color={PRIMARY_BACKGROUND_COLOR}
/>
</TouchableOpacity>
)
}
And the function
const onChangeText = value => {
setSearch(value)
setSearching(value =='' ? false : true)
Helper.getCategoriesSearch(value, (categories) => {
setSearching(false)
//props.searchResults(categories); THIS DO NOT WORK RETURN DATA TO props :(
})
}
Thanks All

react-native-elements checkbox update value

I have the following code and for some reason the checkbox is not updated when I click on them. Does anyone know what might be the problem? I am using CheckBox from react-native-elements. The checked property is based on whether a value exists in a set. The onpress function updates the state variable and I am able to get the correct values from the state variable. Thanks!
constructor(props) {
super(props);
this.state = {
interests: new Set(),
brands: new Set(),
medicalCondition: new Set(),
errorMessage: '',
loading: false
}
}
onPressHandler = (event, value, keyName) => {
let tempCheckedValues = new Set(this.state[keyName]);
tempCheckedValues.has(value) ? tempCheckedValues.delete(value) : tempCheckedValues.add(value);
console.log(tempCheckedValues);
this.setState({[keyName] : tempCheckedValues});
}
renderCheckboxGroup = (checkboxList, keyName) => {
return checkboxList.map((value, index) => {
return (
<CheckBox
key={index}
title={value}
onPress={(event) => this.onPressHandler(event, value, keyName)}
checked={this.state[keyName].has(value.toLowerCase())}
/>
)
})
}
render() {
const interestsConst = ["Tennis", "Golf", "Shopping", "Movie", "Hiking", "Reading", "Diving", "Investing"];
const brandsConst = ["Chanel", "Louis Vuitton", "H&M", "ZARA", "Hermes", "Gucci", "Cartier", "Burberry", "Nike", "Adidas", "Lululemon", "Athleta"];
const medicalConditionConst = ["Hypertension", "Hyperlipidemia", "Diabetes", "Back pain", "Anxiety", "Asthma", "Cancer", "Depression", "Shingles"];
return (
<View style={styles.container}>
<ScrollView>
<View style={styles.cardGroup}>
<Card title='Interests'>
{this.renderCheckboxGroup(interestsConst, 'interests')}
</Card>
</View>
<View style={styles.cardGroup}>
<Card title='Brands'>
{this.renderCheckboxGroup(brandsConst, 'brands')}
</Card>
</View>
<View style={styles.cardGroup}>
<Card title='Medical Conditions'>
{this.renderCheckboxGroup(medicalConditionConst, 'medicalCondition')}
</Card>
</View>
</ScrollView>
</View>
)
}
}

Active is not updating. After a hot reload it is active react native

My child component is below
export default function PickerList ({headingText,listData,hideView,finalpickedItem,onItemSelected,selected} ) {
const {modalHolder,modalHeader,modalHeaderText,modalBody,PerListView,PerListVie wText,okCancel,okCancelHolder,PerListViewActive,
} = styles;
return(
<View style={modalHolder}>
<View style={modalHeader}>
<Text style={modalHeaderText}>{headingText}</Text>
</View>
<View style={modalBody}>
<FlatList data={listData} renderItem={({item , index}) =>
<TouchableOpacity
onPress={() => {
{headingText === 'name'?
onItemSelected(item.name)
: headingText === 'Time' ?
onItemSelected(item.time)
: headingText === 'Property'
onItemSelected(item.property)
}
}}
style={{width:'100%',}}
>
<View
style={
selected===item.name ? PerListViewActive : PerListView > // here i am not getting active hot reload making it active
<Text style={PerListViewText}>
{item.name }
</Text></View>
</TouchableOpacity>
}
keyExtractor={(item, index) => index.toString()}
/>
</View>
</View>
);
};
PickerList.propTypes = {
onItemSelected: PropTypes.func.isRequired,
};
and my parent is
onMenuItemSelected = item => {
console.log(item); // i am getting here selected item
this.setState({ commonSelected: item }); // i am getting final state also.
}
<PickerList
headingText="Property"
listData = {this.state.property_type_options}
hideView = {()=>{this.hideView()}}
finalpickedItem = {()=>{this.finalpickedItem()}}
onItemSelected={this.onMenuItemSelected}
selected = {this.state.commonSelected} /// i have final value here also
/>
issue is "selected" not working every thing is working fine .. selected working but after a hot reload. can i re-render module. state is updating fine but it is not getting active.
I found my answer this is very nice.
extraData={this.state}