Get Key of nested Array from Flatlist - arrays

I have a flatlist that is receiving a friendsArray with the following data structure...
I have a modal that has an onPress function, with that onPress i'd like to get the value of this key. I have the following Code, but usually this code provides me with the key of whatever i just selected in the flatlist... i'd like to get the key of the item selected one level deeper, how do i do this?
Here is App.js
onFriendChatPress = key => {
let friend = this.state.friendsArray.find(game => { return game.key === key })
}
render(){
return{
<View>
<FriendsModal
onChatPress={() => this.onChatPress()}
onClosePress={() => this.closeModal()}
onFriendPress={() => this.onFriendPress()}
onFriendChatPress={() => this.onFriendChatPress()}
selGame={this.state.selGame}
visible={this.state.modalVisible}
selGame={this.state.selGame}
/>
</View>
}
Here is FlatList in the FriendsModal
<FlatList
style={styles.flatList}
data={this.props.selGame.friends}
horizontal={true}
renderItem={(info) => (
<ModalProfileCard
displayName={info.item.displayName}
image={info.item.image}
onFriendPress={() => this.props.onFriendPress(info.item.key)}
onFriendChatPress={() => this.props.onFriendChatPress(info.item.key)}
/>
)
}
/>
Here is the Card in the modal
function modalProfileCard(props) {
return (
<View style={styles.container}>
<TouchableOpacity onPress={props.onFriendsPress} style={styles.friendInfo}>
<Image style={styles.profImage} source={{ uri: props.image }} />
<View style={styles.nameContainer}>
<Text style={styles.name}>{props.displayName}</Text>
</View>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={props.onFriendChatPress}>
{buttonText}
</TouchableOpacity>
</View >
)
}

You can do something like this.
const onPress = (key) => {
//you have the key here
}
return (
<Flatlist
data={your_data}
renderItem={({item})=> <YourComponent {...item} onPress={onPress} />}
/> )
const YourComponent = ({key,onPress}) => {
const onPress = () => {
onPress(key);
}
return (
<TouchableOpacity onPress={onPress}>
</TouchableOpacity>
)
}

Though I understand is
In renderItem, shouldn't you use info.displayName instead of info.item.displayNam? and so on ..
There is also a parent FlatList? You are saving the selected game in state as selGame right? You can save it's index also and can pass to child component so It would be easy to find the selected game's key.

Related

Select single row of Flatlist React native

Hey guys Im making a custom size picker I want to select single size at a time but onPress all item got changed..
my onPress event
onPressItemSize = (item,index:string) => {
this.setState((item) => {
const xl =
xl == item ? this.setState({xl:true}) : this.setState({xl:false});
return { xl };
});
this.setState({selectedSize:item.value})
};
and this is my flatlist component
<FlatList
data={this.state.label}
numColumns={5}
keyExtractor={(item, index) => index.toString()}
extraData={this.state}
renderItem={({item,index}) =>
<View style={{padding:10,}}>
<TouchableOpacity
onPress={this.onPressItemSize.bind(this, item,index)}
style={[styles.Buttoncolor,this.state.xl?null:styles.onfocusbutton]}>
<Text adjustsFontSizeToFit
textTransform='uppercase'
style={[styles.textcolor,this.state.xl?null:styles.white]}>
{item.label}
</Text>
</TouchableOpacity>
</View>
}
/>
Im not sure which state are you trying to set but you need to keen in mind that calling setState will trigger an async function and you need to wait until the new state is successfully changed. i would also use arrow functions for not binding the functions when calling them.
onPressItemSize = (item, index) => {
const { xl } = this.state; //what is xl ?? im assuming it is in your state
const callback = () => {console.log("State changed");}
var newXL = false;
if(xl === item){
newXL = true
}
//you can set diferents values at the same time
this.setState({xl: newXL, selectedSize: item.value }, callback)
};
<FlatList
data={this.state.label}
numColumns={5}
keyExtractor={(item, index) => index.toString()}
extraData={this.state}
renderItem={({item, index}) =>
<View style={{padding:10,}}>
<TouchableOpacity
onPress={() => onPressItemSize(item, index)} //changed
style={[styles.Buttoncolor,this.state.xl?null:styles.onfocusbutton]}>
<Text adjustsFontSizeToFit
textTransform='uppercase'
style={[styles.textcolor,this.state.xl?null:styles.white]}>
{item.label}
</Text>
</TouchableOpacity>
</View>
}
/>

Access specific row data on FlatList - react native

Hi I'm making an api request, rendering results using FlatList like this:
<TouchableOpacity onPress={this._onPressButton}>
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<TouchableOpacity
activeOpacity={0.8}
onPress=this._onPressButton}>
<ListItem
title= {`${item.companyName}`}
subtitle= {`[ ${item.symbol} ] ${item.change}%`}
/>
</TouchableOpacity>
my goal is to access data on specific rows, let's suppose I created a function that make an alert:
_onPressButton = () => {
alert('What should search for here?')
};
How to access item.companyName ?
You could:
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<TouchableOpacity
activeOpacity={0.8}
onPress={()=>this._onPressButton(item.companyName)}>
<ListItem
title= {item.companyName}
subtitle= {`[ ${item.symbol} ] ${item.change}%`}
/>
with
_onPressButton = (companyName) => {alert(companyName)};

Cant add function to create dynamic button inside renderItem FlatList

I am trying to add a function to return button text based on the state inside the renderItem FlatList component.
renderButton() {
return <Text>Button</Text>;
}
<TouchableWithoutFeedback>
<TouchableOpacity>
{this.renderButton()}
</TouchableOpacity>
<TouchableWithoutFeedback>
This code return an error
function this.renderButton is not a function
Update:
<FlatList
data={list}
renderItem={this.renderRow}
/>
renderRow({item}) {
return(
<TouchableWithoutFeedback>
<TouchableOpacity>
{this.renderButton()}
</TouchableOpacity>
<TouchableWithoutFeedback>
);
}
renderButton() {
return <Text>Button</Text>;
}
You need to bind the renderRow function to be able to access this.renderButton in it.
<FlatList
data={list}
renderItem={this.renderRow.bind(this)}
/>
or
<FlatList
data={list}
renderItem={() => this.renderRow()}
/>
or
renderRow = ({item}) => {
return(
<TouchableWithoutFeedback>
<TouchableOpacity>
{this.renderButton()}
</TouchableOpacity>
<TouchableWithoutFeedback>
);
}

Pass function requiring parameter to PureComponent properly

I am using FlatList and in my renderItem I have a PureComponent called GridItem. I am trying to pass the function wishlistAddPresed which requires the item parameter, however when done this way, the PureComponent items are all rerendering on every state change even if "item" has not changed.
How do I fix this? Thank you!
wishlistAddPresed = (item) => console.log(item)
renderItem = ({item}) => {
return (
<GridItem
item={item}
wishlistAddPresed={this.wishlistAddPresed(item)}
/>
)
}
render () {
console.log("Render products grid");
return(
<View style={styles.container}>
<FlatList
data={this.state.data}
renderItem={this.renderItem}
keyExtractor={(item, index) => item.id}
/>
</View>
);
}
In my GridItem's render I have:
<TouchableOpacity style={styles.colButtonsG} onPress={this.props.wishlistAddPresed}>
<IconG name='playlist-add-check' size={26} color="green" style={styles.icon} />
</TouchableOpacity>
The trick is to pass both the callback function AND the parameter (which you are already doing) and then inside the nested component, pass the item to an anonymous callback. So in your case, you would need to do the following:
<FlatList
data={this.state.data}
renderItem={({ item }) => {
return <GridItem item={item} wishlistAddPressed={this.wishlistAddPressed} />
}}
keyExtractor={(item, index) => item.id}
/>
And for the GridItem which extends PureComponent...
class GridItem extends React.PureComponent {
render() {
const {item, wishlistAddPresed} = this.props;
return (
<TouchableOpacity onPress={() => wishlistAddPressed(item)}>
<IconG name="playlist-add-check" size={26} color="green" style={styles.icon} />
</TouchableOpacity>
);
}
}
Done this way, wishlistAddPressed gets called with the specific item for that row and the function equality is maintained so that the PureComponent doesn't re-render improperly like it should.

Pass callback with parameters to parent component

I am asking something that is probably trivial but that has been bugging me for a while.
Lets say we have a CHILD component that renders some buttons:
const Picker = ({ data, label, visible, cancelCallback, onPressCallback }) => {
function renderRow (data) {
return data.map((el) => {
return (
<TouchableOpacity
style={listViewItemContainer}
key={el.label}
onPress={}
>
<Text style={listViewItem}> { el.label } </Text>
</TouchableOpacity>
);
});
}
return (
<Modal
visible={visible}
animationType="fade"
onRequestClose={() => {}}
transparent={true}
>
<View style={listViewContainerStyle}>
{ renderRow(data) }
</View>
</Modal>
);
};
Now when I press one of those buttons I want to make a callback to the parent BUT I want to pass some parameters like the label of the element pressed. Something like:
<TouchableOpacity
style={listViewItemContainer}
key={el.label}
onPress={onPressCallback(el.label)} // onPressCallback is a Prop passed to the child
>
<Text style={listViewItem}> { el.label } </Text>
</TouchableOpacity>
And then handle the logic in the parent component.
How can I do this?
Like this.
onPress={() => onPressCallback(el.label)}

Resources