Active is not updating. After a hot reload it is active react native - 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}

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.

How to change icon depending on which array item is pressed in React Native?

I have an array of details on a collapsible component, how can I change the icon chevron-down to chevron-up and vice versa depending on which item on .map() is pressed?
The problem is when I tap on an item all the icons of the other items changes with the state.
How to change state only for an item in array?
Here is my code:
const [iconName, setIconName] = useState("chevron-down")
return (
<AppScreen>
<ScrollView style={styles.container}>
{
terms.map((term, index) => {
return (
<Collapse
key={index}
style={styles.overlayContainer}
onToggle={() => iconName === "chevron-down" ? setIconName("chevron-up") : setIconName("chevron-down")}
>
<CollapseHeader style={styles.collapseHeaderStyle}>
<View style={styles.collapseHeaderStyle}>
<AppText style={styles.title}>{term.title}</AppText>
</View>
<AppIcon iconName={iconName} iconType="ionicon" iconColor={colors.secondary} />
</CollapseHeader>
<CollapseBody style={styles.collapseBody}>
{
terms[index].contents.map((content, index) => {
return (
<React.Fragment key={index} >
<AppText style={styles.content}>{content.content}</AppText>
</React.Fragment>
)
})
}
</CollapseBody>
</Collapse>
)
})
}
</ScrollView>
</AppScreen >
)
you need to modify the terms array and keep track of it. Accoriding to the value returned you can display the icon that you want. here is a basic example of how this can be achieved.
const [iconName, setIconName] = useState("chevron-down")
const [terms, setTerms] = useState([])
const handlePress = (index) => {
const arr = [...terms]
arr[index].collapsed = !arr[index].collapsed
setTerms(arr)
}
return (
<AppScreen>
<ScrollView style={styles.container}>
{
terms.map((term, index) => {
return (
<Collapse
key={index}
style={styles.overlayContainer}
onToggle={() => handlePress(index)}
>
<CollapseHeader style={styles.collapseHeaderStyle}>
<View style={styles.collapseHeaderStyle}>
<AppText style={styles.title}>{term.title}</AppText>
</View>
{/* Display the icon based on true or false */}
<AppIcon iconName={term.collapsed ? "chevron-down" : "chevron-up"} iconType="ionicon" iconColor={colors.secondary} />
</CollapseHeader>
<CollapseBody style={styles.collapseBody}>
{
terms[index].contents.map((content, index) => {
return (
<React.Fragment key={index} >
<AppText style={styles.content}>{content.content}</AppText>
</React.Fragment>
)
})
}
</CollapseBody>
</Collapse>
)
})
}
</ScrollView>
</AppScreen >
)

React-Native how to show different API by same id in Flatlist

i have two different API and i want show two API in one Flatlist this is worked (look the picture). i show it using filter by id API (if API have same id will show). My question is how to remove/hide/dont show null value flatlist (look the picture)?
Im using API from https://jsonplaceholder.typicode.com
picture my app
const {user, post} = useSelector(state => state.reducer);
const dispatch = useDispatch();
const getData = [...user, ...post];
useEffect(() => {
dispatch(getProfile());
dispatch(getPost());
}, []);
const tailwind = useTailwind();
const renderPost = ({item}) => {
const renUsr = user.filter(renUsr => renUsr.id === item.userId);
return (
renUsr.id !== item.userId ? (
<View style={tailwind('pb-4')}>
<View style={tailwind('px-4 py-4 bg-gray-200 mx-6 rounded-[20px]')}>
<View style={tailwind('flex flex-row')}>
<Image style={tailwind('rounded bg-black w-8 h-8')} />
{renUsr.map(posting => (
<Text
key={posting.id}
style={tailwind('pl-2 font-semibold py-2')}>
{posting.name}
</Text>
))}
</View>
<View style={tailwind('mt-2')}>
<TouchableHighlight
style={styles.touchHighlight}
onPress={navigation}>
<View style={tailwind('bg-gray-200 p-1')}>
<Text key={item.id}>{item.body}</Text>
</View>
</TouchableHighlight>
</View>
</View>
</View>
) : (
null
)
);
};
return (
<FlatList
data={getData}
renderItem={renderPost}
keyExtractor={item => item.id}
/>
);
};
user.filter(renUsr => renUsr.id === item.userId);
Instead of using the filter here, just filter the list passed to the flatlist so you it will be looped only once and you don't to filter for every single item

FlatList not rendering style dynamically

I'm currently struggling in making my FlatList applying the changes I do to it. What I am wanting right now is that when I click an item in my flatlist, that it highlights in a certain color. I followed an approach done by a guy but I am having the problem that to me is not working the update once I click.
I can see through console that all I am doing performs a modification but I think that I am missing some point with extraData parameter since it is not re-rendering with the backgroundColor that I would like to apply.
The code I have is as following, I know that the style I am applying is correct since if i substitute in the map styles.list per styles.selected, everything gets the background I would like to be applied to the elements I click.
So summarizing, the issue I think I have is that the flatlist is not re-rendering so it doesn't show the modifications I perform on it. Any idea of what I am doing wrong? Any tip?
render() {
const { students, studentsDataSource, loading, userProfile } = this.props.navigation.state.params.store;
this.state.dataSource = studentsDataSource._dataBlob.s1.map(item => {
item.isSelect = false;
item.selectedClass = styles.list;
return item;
})
const itemNumber = this.state.dataSource.filter(item => item.isSelect).length;
return (
<View style={styles.container}>
<Item rounded style={styles.searchBar}>
<Input placeholder='Group Name'/>
</Item>
<FlatList
style={{
flex: 1,
width: "100%",
}}
data={this.state.dataSource}
ItemSeparatorComponent={this.FlatListItemSeparator}
renderItem={ ({ item }) => (
<ListItem avatar style={[styles.list, item.selectedClass]}
onPress={() => this.selectItem(item)}>
<Left>
{!item.voteCount && <Avatar unseen={true} /> }
{!!item.voteCount > 0 && <Avatar />}
</Left>
<Body>
<Text>{item.name}</Text>
<Text note>{item.group}</Text>
</Body>
</ListItem>
)
}
listKey={item => item.key}
extraData={this.state}
/>
</View>
);
}
Here we can find the state and SelectItem functions:
constructor(props) {
super(props)
this.state = {
dataSource : [],
}
}
//FlatListItemSeparator = () => <View style={styles.line} />;
selectItem = data => {
//{console.log("inside SelectItem=", data)}
data.isSelect = !data.isSelect;
data.selectedClass = data.isSelect? styles.selected: styles.list;
const index = this.state.dataSource.findIndex( item => data.key === item.key);
this.state.dataSource[index] = data;
this.setState({
dataSource: this.state.dataSource,
});
console.log("This state has the changes:=",this.state.dataSource)
};
Well the main issue was that I was not using the .setState and instead I was doing assignations which killed the listeners.

Not able to set active and inactive images in 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 :