To add multiple data in one container in flatlist - react-native

Hello I am new in react native. I am working on flatlist I want multiple items to be shown in list in one container. Example I want to add multiple data in one container. My code is given below any help will be appreciated.
this.state = {
FlatListItems: [
{ key: "Skptricks" },
{ key: "Sumit" },
{ key: "Amit" },
{ key: "React" },
{ key: "React Native" },
{ key: "Java" },
]
};
and the I have print the key.
<View style={styles.container}>
<FlatList
data={ this.state.FlatListItems }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item}) =>
<Text style={styles.item} onPress={this.GetItem.bind(this, item.key)} >
{item.key} </Text>
}
/>
</View>
i want this kind of layout i have flatlist i want to show thw data like this given in image.

Modify state as below, add more items similar to data & key
this.state = {
FlatListItems: [
{ key: "Skptricks", data: "one" },
{ key: "Sumit" , data: "two"},
{ key: "Amit" , data: "three"},
{ key: "React", data: "four" },
{ key: "React Native" , data: "five"},
{ key: "Java", data: "six" },
]
};
And render it inside the FLatlist as :
<View style={styles.container}>
<FlatList
data={ this.state.FlatListItems }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item}) =>(
<View>
<Text style={styles.item} onPress={this.GetItem.bind(this, item.key)} >
{item.key} </Text>
<Text {item.data} </Text>
</View>
)}
numColumns={2}
keyExtractor={(item, index) => index}
/>
</View>

just add them as as keys in your sample array of objects. and access them in item in your FlatList component.
FlatListItems: [
{ title: "Skptricks",subTitle:"Asdasd" },
{ title: "melons",subTitle:"melons are great" }
]
and in your FlatList component
<FlatList
data={ this.state.FlatListItems }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item}) =>
(<View>
<Text style={styles.item} onPress={this.GetItem.bind(this, item.key)} >
{item.title} </Text>
<Text style={styles.item} onPress={this.GetItem.bind(this, item.key)} >
{item.subTitle} </Text>
</View> )
}
keyExtractor={(item,index)=>index}
/>
Edit: give the numColumns prop to FlatList Component as
numColumns={2}

Related

How can I add a search bar with a flat list in react native (no json)?

I am building an app, where I have a list and I would like to search the items in the list with a search input how can I do?
const videos = [
{name: 'Unity Pro', link:'https://www.youtube.com/watch?v=A7btOci5Gs4&t',key:'1'},
{name: 'video2', link:'https://www.youtube.com/watchv=K36nOkqjbso&ab_channel=AppleExplained',key:'2'},
{name: 'video3', link:'https://www.youtube.com/watch?v=A7btOci5Gs4&t',key:'3'},
]
const ListVideos = ({navigation}) => {
return(
(code....)
<FlatList data={videos}
renderItem={({ item }) => (
<TouchableOpacity style={styles.button} onPress={() => {Linking.openURL(item.link)}}>
<IonIcon name="open-outline" size={16} color="white" style={{justifyContent:"center", alignContent:'center', alignItems:"center", alignSelf:"center", paddingRight:10}}/>
<Text style={styles.inbuttonText} >{item.name}</Text>
</TouchableOpacity>
)}
>
</FlatList>
Use TextInput to filter your list. Set a state for your current variable and a data that will be filtered using your current input text. Something like this.
const [searchText, setSearchText] = useState();
//filtering
const searchFilteredData = searchText
? flatListData.filter((x) =>
x.<filterItem>.toLowerCase().includes(searchText.toLowerCase())
)
: flatListData;
Then, in your render for TextInput:
<TextInput
placeholder="Search..."
style={}
onChangeText={(text) => {
setSearchText(text);
}}
value={searchText}
/>
and your flatlist:
<FlatList
data={searchFilteredData}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
change filterItem based on your data structure. For example your data looks like this:
data = [
{
id: "1",
name: "John Smith",
},
{
id: "2",
name: "John Willow",
},
use x.name in the filter function.

FlatList renderItem returning undefined

i have a flatList that renders a component with some props, but the renderItem returns me 'undefined'. I´m new to react-native and I cant´t find a solution. Thanks
edit:
Is it possible that the styles I used in 'posts.js' may affect the flatList render?
Feed.js:
export default function Feed() {
const Posts = [
{ id: 1, title: "eu", photoDesc: 'eu' },
{ id: 2, title: "me", photoDesc: 'me' }
]
console.log;
return (
<FlatList
keyExtractor={props => props.id}
data={Posts}
renderItem={({ item }) => <FeedPosts title={`${item.title}`} photoDesc={`${item.photoDesc}`} ></FeedPosts>}
>
</FlatList>
);
}
Posts.js:
export default function FeedPosts(props) {
return (
<Container>
<Header>
<TouchableOpacity>
<FontAwesome5 name='bell' size={40} style={{ marginLeft: 10 }}></FontAwesome5>
</TouchableOpacity>
<TouchableOpacity>
<Ionicons name='add-circle' size={40} style={{ marginRight: 5 }}></Ionicons>
</TouchableOpacity>
</Header>
<Body>
<Time>15/12/2021 as 17:42pm</Time>
<User>
<Icon source={require('../../assets/vibe.jpg')}></Icon>
<Description>{props.title}</Description>
</User>
<Content>
<PetPhoto source={props.postImg}></PetPhoto>
</Content>
<ContentDesc >
<PhotoDesc> {props.photoDesc}</PhotoDesc>
</ContentDesc>
<Bottom>
<Comment title="Comment" placeholder="Escrever Comentário"></Comment>
</Bottom>
<Buttons></Buttons>
</Body>
</Container>
);
}
Your variable Posts contains an array of React components. Instead, it should contain an array of data that you transform into components.
So your Posts should look more like this:
const Posts = [
{title: "My title", photoDesc: "Desc"},
{title: "My title2", photoDesc: "Desc2"},
{title: "My title3", photoDesc: "Desc3"}
]
Here's an example (straight from the React Native documentation) of how this works in context:
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
{
id: '58694a0f-3da1-471f-bd96-145571e29d72',
title: 'Third Item',
},
];
const Item = ({ title }) => (
<View style={styles.item}>
<Text style={styles.title}>{title}</Text>
</View>
);
const App = () => {
const renderItem = ({ item }) => (
<Item title={item.title} />
);
return (
<SafeAreaView style={styles.container}>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
}
(https://reactnative.dev/docs/flatlist)
You can see in the above example that DATA is an array of objects, which gets transformed with the function renderItem into components. Very similar to your use case.

react-native changes the properties of the elements in the array?

I have a FlatList and I want to implement a radio button.My idea is to change the selected property of an element in this.state.data to control it,but I am a newbie, I don't know how to change the property of an element in this.state.data.
Here is my code:
this.state = {
data: [
{
month:1,
price:18,
selected:true
},
{
month:3,
price:48,
selected:false
},
{
month:12,
price:128,
selected:false
},
],
};
<FlatList
data={this.state.data}
renderItem={({item, index, separators}) => (
<TouchableOpacity onPress={() => this.radio(index,item)}>
<View style={item.selected ? {borderWidth:3,borderColor:'#FFA371',borderRadius:15}:{}}>
<View style={styles.itemDefalut}>
<View style={{ flexDirection: "column", flex: 1 }}>
<Text>
Months
</Text>
<Text>{item.month} Months</Text>
</View>
<View>
<Text>${item.price}</Text>
</View>
</View>
</View>
</TouchableOpacity>
)}
/>
radio(index,item) {
for (var variable in this.state.data) {
variable.selected = false;
}
item.selected = true;
}
first pass only index from onpress
onPress={() => this.radio(index)
then in radio function do something like this
radio = index => {
let data = [ ...this.state.data ];
this.state.data.map((elem,key)=>{
if(elem.month==data[index].month){
data[key]={...data[key], selected: true};
}else{
data[key]={...data[key], selected: false};
}
})
this.setState({ data:data});
}
radio(item) {
let data = [...this.state.data];
let index = data.findIndex(el => el.month === item.month);
data[index] = {...data[index], selected: !item.selected};
this.setState({ data });
}
In TouchableOpacity on press it should be
<TouchableOpacity onPress = {this.radio.bind(this,item)}>

changing text in Flatlist for each item

Hey guys I would like to know how to change text in each row of a Flatlist.
I want to be able to toggle between follow and unfollow.
Here's my code example :=>
this.state = {
FlatListItems : [
{"key": "MARIA", "image":require("./assets/image/maria.jpg")},
{"key": "MARTA", "image":require("./assets/image/marta.jpg")},
{"key": "MARTIN", "image":require("./assets/image/martin.jpg") },
{"key": "OLIVIA", "image":require("./assets/image/olivia.jpg") },
],
checked:true,
}'
And here's the checked function
checked=()=>{
if(checked==true)
{
this.checked.setState(true)
}
else{
this.checked.setState(False)
}
}
And here's the render function
<FlatList
contentContainerStyle={{
flexDirection: 'row',alignItems:'center',paddingLeft:10,borderTopRightRadius:10,borderTopLeftRadius:10,
flexWrap: 'wrap',}}
data={ this.state.FlatListItems }
ItemSeparatorComponent = {this.FlatListItemSeparator}
renderItem={({item,key}) =><View style={{padding:5,borderTopRightRadius:10,borderTopLeftRadius:10,}}>
<ImageBackground source={item.image}
style={{height:230,width:185,borderTopRightRadius:10,borderTopLeftRadius:10}}
blurRadius={ Platform.OS == 'ios' ? 10 : 6 } >
<View style={{alignItems:'center',padding:20,backgroundColor:'rgba(0,0,12, 0.4)'}}>
<View style={{alignItems:'center',padding:20}}>
<Image source={item.image} style={{width: 90, height: 90, borderRadius: 60}}/>
</View>
<View style={{alignItems:'center',paddingTop:10}}>
<Text style={{fontSize:18,fontFamily:'CRC55',color:'white'}}>{item.key}</Text>
<Text style={{fontSize:22,fontFamily:'CRC55',color:'white',paddingTop:10}}>{item.key}</Text>
<View style={{backgroundColor:'white',width:185,height:10}}>
</View>
</View>
</View>
</ImageBackground>
{
!this.state.checked? <TouchableOpacity onpress={this.checked}
><Text style={{fontSize:20,alignItems:'center'}}>FOLLOWING</Text></TouchableOpacity>: <TouchableOpacity onpress={()=>{this.setState({checked:key})}}><Text style={{fontSize:20,alignItems:'center'}}>FOLLOW</Text></TouchableOpacity>
}
</View>
}
/>
My question is how can I toggle between follow and unfollow for each item in the Flatlist.
You can use directly this example. I have just used some code from offical docs. You keep each list item state separately. You can adjust this code easily for your needs
import React, { Component } from 'react'
import { Text, View, FlatList, TouchableOpacity } from 'react-native'
const data = [
{ "key": "MARIA", "title": "image MARIA", "id": 1 },
{ "key": "MARTIN", "title": "image MARTIN", "id": 2 },
{ "key": "OLIVIA", "title": "image OLIVIA", "id": 3 },
];
class MyListItem extends React.PureComponent {
state = {
selected: true
}
_onPress = () => {
this.setState({
selected: !this.state.selected
})
};
render() {
const text = this.state.selected ? "follow" : "unfollow";
return (
<TouchableOpacity onPress={this._onPress}>
<View>
<Text >
{this.props.title + " " + text}
</Text>
</View>
</TouchableOpacity>
);
}
}
export default class MultiSelectList extends React.PureComponent {
_keyExtractor = (item, index) => item.id;
_renderItem = ({ item }) => (
<MyListItem
id={item.id}
title={item.title}
/>
);
render() {
return (
<FlatList
data={data}
extraData={this.state}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
/>
);
}
}

React Native FlatList Touchable Opacity

I used FlatList to display the title that is in the data. I added in TouchableOpacity for the FlatList. So for example, when I click 'First', I want to show the the data from 'mood' and it will show the list of passionate,rousing and confident. I want to show the list on a new file/screen and show purely the mood of list.
This is my data:
const Mock =
[
{ title: 'First',
mood:
[
{name: 'passionate'},
{name: 'rousing'},
{name: 'confident'},
],
},
{ title: 'Second',
mood:
[
{name: 'rollicking'},
{name: 'cheerful'},
{name: 'fun'},
{name: 'sweet'},
{name: 'amiable'},
{name: 'natured'}
],
This is my FlatList code:
export default class Cluster1 extends Component{
render() {
return (
<View>
<FlatList
data={Mock}
renderItem={({ item, index }) => {
return <FlatListItem item={item} index={index} />;
}}
/>
</View>
);
}
}
class FlatListItem extends Component {
render() {
return (
<View style={styles.list}>
<View>
<TouchableOpacity>
<Text style={styles.itemTitle}>{this.props.item.title}</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
What should I do with the TouchableOpacity when I want to show the mood name when I click the title?
This is my style code
const styles = StyleSheet.create({
itemTitle:{
fontSize: 25,
fontWeight: 'bold',
color: 'white',
margin: 20,
},
},
list:{
flex: 1,
backgroundColor: '#00BCD4',
alignItems: 'center',
justifyContent: 'space-between',
flexDirection: 'row',
},
});
You should modify your code as below to do this:
export default class Cluster1 extends Component {
render() {
return (
<View style={{ margin: 30, backgroundColor: '#ddd' }}>
<FlatList
data={Mock}
renderItem={({ item, index }) => {
return <FlatListItem item={item} index={index} />;
}}
/>
</View>
);
}
}
class FlatListItem extends Component {
state = { showItemIndex: [false, false] };
_onPress = index => () => {
let showItemIndex = this.state.showItemIndex;
showItemIndex[index] = !this.state.showItemIndex[index];
this.setState({ showItemIndex });
};
render() {
return (
<View style={styles.list}>
<View>
<TouchableOpacity onPress={this._onPress(this.props.index)}>
<Text style={styles.itemTitle}>{this.props.item.title}</Text>
</TouchableOpacity>
{this.state.showItemIndex[this.props.index] && (
<FlatList
data={this.props.item.mood}
extraData={this.state.showItemIndex}
renderItem={({ item, index }) => {
return (
<Text item={item} index={index}>
{item.name}
</Text>
);
}}
/>
)}
</View>
</View>
);
}
}
Use this, it's should be work fine for you:
Link: https://github.com/oblador/react-native-collapsible
Link: https://github.com/naoufal/react-native-accordion
Link: https://github.com/cuiyueshuai/react-native-expandable-section-flatlist
You could set a state variable which gets updated whenever your TouchableOpacity gets pressed. And then you conditionally render the title or the list of mood names:
class FlatListItem extends Component {
constructor(props) {
super(props);
this.state = {collapsed: true}
}
render() {
return (
<View style={styles.list}>
<View>
<TouchableOpacity
onPress={this.onPress}
>
<Text style={styles.itemTitle}>
{this.props.item.title}
</Text>
</TouchableOpacity>
{this.state.collapsed ?
<View /> :
<View>
{this.props.item.mood.map(mood => <Text>{mood.name}</Text>)}
</View>}
</View>
</View>
);
}
onPress = () => {
this.setState({collapsed: !this.state.collapsed})
}
}
You can do this by separating out the datasource that is required to show in the list.
First to display title: you can do something like this
export default class Cluster1 extends Component {
state = {
data: []
};
componentWillMount() {
const titles = Mock.forEach(data => data.title);
this.setState({
data: titles
});
}
onItemClick = item => {
const itemIndex = Mock.findIndex(data => (
data.title === item
));
const values = Mock[itemIndex].mood;
this.setState({
data: values
});
};
render() {
return (
<View>
<FlatList
data={this.state.data}
renderItem={({ item, index }) => {
return (
<FlatListItem
item={item}
index={index}
onItemClick={this.itemClick}
/>
);
}}
/>
</View>
);
}
}
and then in your FlatlistItem code:
class FlatListItem extends Component {
render() {
return (
<View style={styles.list}>
<View>
<TouchableOpacity onPress={() =>
this.props.onItemClick(this.props.item)
}>
<Text style={styles.itemTitle}>
{
this.props.item.name ?
this.props.item.name : this.props.item
}
</Text>
</TouchableOpacity>
</View>
</View>
);
}
}