I'M new to RN and need some help
I have an object like
{title:"title",price:"price",subtitle:"subtitle"}
And I'd like to use 2 values at flatlist, like here -
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<ListItem
title={`${item.name.first} ${item.name.last}`}
subtitle={item.email}
/>
)}
/>
</List>
But in this example wasn't show structure of data so I'm confused what should I do. Please help me to solve it!
At the end (render) I need a ListItem this view -
(title) (price)
Or I should better use native-base, but the same questions about 2 value, passing to list item
You have to pass an array into the data property, then you can do:
<FlatList
data={this.state.data}
renderItem={({ item }) => ( //this part will iterate over every item in the array and return a listItem
<ListItem
key={item.id}
title={item.title}
price={item.price}
/>
)}
/>
</List>
Related
I have a Flatlist on react native by which its working perfectly, recently saw an UI which has a custom designed compoenent in between the list, kindly check the below reference image
Check this image, a new design named "Safety+" has been added inside an list, How to do this ?
Need to add custom design like below randomly inside and already rendered flatlist ! How to achieve this , as i couldn't find or understand where to start
Please check the image and help in achieving this:
<FlatList
contentContainerStyle={{ paddingBottom: 50 }}
data={this.state.availableBusList}
keyExtractor={item => item.id}
renderItem={({item}) => {
return(
<TouchableOpacity style={styles.busCardContainer}
onPress={() => {
console.log(item);
//this.props.navigation.navigate('SeatLayout')
}}
<Text>{item.name}</Text>
>)}}
/>
This is my flatlist code
You can return a fragment with your component and a randomly included component. The condition for inclusion is up to you, i.e. complete chance, every 5th element, etc.
<FlatList
contentContainerStyle={{ paddingBottom: 50 }}
data={this.state.availableBusList}
keyExtractor={item => item.id}
renderItem={({item}) => {
return(
<Fragment>
<TouchableOpacity style={styles.busCardContainer}
onPress={() => {
console.log(item);
//this.props.navigation.navigate('SeatLayout')
}}
>
<Text>{item.name}</Text>
</TouchableOpacity>
{Math.random() < 0.5 && ( // example 50% chance to include random component
<RandomComponent>...</RandomComponent>
)}
</Fragment>
)}}
/>
You can render conditionally in your renderItem function: https://reactjs.org/docs/conditional-rendering.html
Additionally, if you want to render your custom component at specific indexes, you can also put index parameter into renderItem. Here is my example:
<FlatList
contentContainerStyle={{ paddingBottom: 50 }}
data={this.state.availableBusList}
keyExtractor={item => item.id}
renderItem={({ item, index }) => {
return index % 5 === 0 ? <CustomComponent /> : <NormalComponent />;
}}
/>
Really stumped. I am trying to create a ListItem for every key of every value in an array of objects. When I log item, it returns the key I'm looking for as a string. Great! However, the list items never render on the page.
return (
<div>
<List className="list">
{Object.values(props.sectionInfo).forEach(section => {
Object.keys(section).map((item, index) => {
return (
<ListItem button className='list-item'> //doesn't render, but also doesn't throw errors
<ListItemText primary={item} />
</ListItem>
)
});
})}
</List>
</div>
);
console.log(item) //returns "red", "blue"
The below renders the list perfectly, however the list items are the indexes (0, 1)
return (
<div>
<List className="list">
{Object.keys(props.sectionInfo).map((section, index) => {
return (
<ListItem button className='list-item'>
<ListItemText primary={section} />
</ListItem>
)
})}
</List>
</div>
);
Any insight would be helpful.
This is because you are using the forEach in the outer loop and it doesn't return anything actually, so the children prop of the List is undefined. Try this:
return (
<div>
<List className="list">
{Object.values(props.sectionInfo).map(section => {
return Object.keys(section).map((item, index) => {
return (
<ListItem button className='list-item'>
<ListItemText primary={item} />
</ListItem>
)
});
})}
</List>
</div>
);
Please try to build list of virtual doms as following:
let items = []
Object.values(props.sectionInfo).forEach(section => {
let subItems = Object.keys(section).map((item, index) => {
return (
<ListItem button className='list-item'> //doesn't render, but also doesn't throw errors
<ListItemText primary={item} />
</ListItem>
)
});
items = items.concat(subItems);
})
return (
<div>
<List className="list">
{items}
</List>
</div>
);
Have you tried going through Object.values(section) in the second loop?
Because from your second statement it seems like the contents are indexed as an Array. Maybe you can give more information about the data structure to help you further.
I am wondering which is the right way to assign onPress function for the FlatList item in React-Native. My mentor has explained for me that maybe I missed the knowledge of "delegate/closure/block" definition in OOP, I had read it but until now I still cannot figure it out by myself. This is the detail:
I have a screen named Menu – this menu has a <FlatList> which contains multiple <MenuItem>, each <MenuItem> has a toggle button to "add item to cart" or "remove item for cart" (click to add – click again to remove). I seperate <MenuItem> to another file so my current folder-tree looks like this:
__Menu
| |_MenuItem
| |__index.js
|
|__index.js
And this is my mentor's approach:
He defined a function named _onToggleCart in Menu/index.js like this:
_onToggleCart = (selected) => {
if(selected == false){
this.props.addItemToCart()
}else{
this.props.removeItemFromCart()
}
}
<FlatList
data={data}
initialNumToRender={6}
extraData={this.state.data}
keyExtractor={(item) => item.id}
renderItem={({ item, index }) => <MenuItem item={item} isFinalItem={index == data.length - 1} navigation={navigation} onPress={this._onToggleCart} />}
/>
Menu/MenuItem/index.js looks like this:
...
const [selected, setSelected] = useState(false)
const { id, imgURL, name, desciption, total } = item
_onChangeCart = () => {
setSelected(!selected)
onPress(selected)
}
...
<TouchableOpacity>
...
<TouchableWithoutFeedback onPress={this._onChangeCart}>
...
</TouchableWithoutFeedback>
...
</TouchableOpacity>
And this is my approach:
In Menu/index.js I do not assign any function to <MenuItem>, so I don't have a function _onToggleCart and also don't have onPress props. It looks like this:
<FlatList
data={data}
initialNumToRender={6}
extraData={this.state.data}
keyExtractor={(item) => item.id}
renderItem={({ item, index }) => <MenuItem item={item} isFinalItem={index == data.length - 1} navigation={navigation} />}
/>
In Menu/MenuItem/index.js to check the condition in _onChageCart like this:
...
const [selected, setSelected] = useState(false)
const { id, imgURL, name, desciption, total } = item
_onChangeCart = () => {
if(selected == false){
this.props.addItemToCart()
}else{
this.props.removeItemFromCart()
}
}
...
<TouchableOpacity>
...
<TouchableWithoutFeedback onPress={this._onChangeCart}>
...
</TouchableWithoutFeedback>
...
</TouchableOpacity>
Can anyone help me what is different between them and which is better?
The main difference from you component and the one of your mentor is that he passes a onPress prop to MenuItem. What difference does this makes?
Well, in your example, if you need to add more action on the MenuItem press, how do you do? You can't do it, but the way your mentor did, you can add more functionality (call one more function) to the MenuItem because he call props.onPress.
You mentor did a more flexible component, wich maybe can grow easier, your component is more fixed.
Wich one is better? Now that is up to you and the structure of your project.
Here I am trying to display an array called "posts" in a FlatList.
render() {
console.log(this.props.posts);
return (
<View style={this.styles.container}>
<FlatList
data={this.props.posts}
renderItem={(item) => <Text> {item.name} </Text>}
/>
</View>
);
}
As seen in this console log, the posts array is correctly populated.
But the above code doesn't display any data in the FlatList.
However, in renderItem, if I add an extra "item" property it works.
renderItem={(item) => <Text> {item.item.name} </Text>}
What is the reason for this behavior.
Input of ReactNative's FlatList is not item, but an object containing 3 parameters: item for actual data, index for index and separators object to customize your item component. What you did is naming that object item, and get actual item from the object.
To avoid confusion, consider using ES6 shorthand:
renderItem={({ item, index }) => <Text> {item.name} </Text>}
This is a common behavior. You can get required behavior by doing object destructuring as:
<FlatList
data={this.props.posts}
renderItem={({item}) => <Text> {item.name} </Text>}
/>
If you are rendering complex component, then you might want to do like this for sake of readability of the code however.
<FlatList
data={this.props.posts}
renderItem={this.renderItem} />
renderItem = ({item}) => {
return (
<Text>{item.name}</Text>
)
}
Might wanna look into your question here though.
ReactNative Flatlist - RenderItem not working
I want to get a value from the state based on the item that the flatlist is rendering like so this.state.liked[item.apiName] i don't know why it doesn't work.
FlatList:
<FlatList
refreshing={this.props.loading}
onRefresh={this.props.refresh}
data={this.props.series}
renderItem={({ item }) => (
<Serie
serie={item}
onPress={this._onPressButton}
handleLike={this._likeSerie}
liked={this.state.liked[item.apiName]}
/>
)}
keyExtractor={item => item.id}
/>
Apparently addding the extraData={this.state.liked} prop fixed the issue