I have passed component as argument, now how to render the component? - react-native

Below in a code I have describe the question as comment
//This is MessagesScreen.js
<FlatList
data={messages}
keyExtractor={messages => messages.id.toString()}
renderItem={({ item }) =>
<ListItem style={styles.listItem}
title={item.title}
subTitle={item.description}
image={item.image}
DeleteIconView={ListItemDeleteAction} /*Here ListItemDeleteAction.js
is component want to pass it to
the ListItem.js. Note: I have
imported all the nessory
labries*/
onPress={() => handleDelete(item)}
//renderRightActions={ListItemDeleteAction}
/>
}
ItemSeparatorComponent={ListItemSeparator}
refreshing={refreshing}
onRefresh={() => {
setMessages([
{
id: 2,
title: 'Komail',
description: 'React-Native Developer',
image: require("../asserts/komail.jpg"),
}
])
}}
/>
This is ListItemDeleteAction.js, which I want to render in ItemList.js
//This is ListItemDeleteAction.js
function ListItemDeleteAction(props) {
return (
<View style={styles.container}>
<MaterialCommunityIcons name="trash-can" size={30} color={Colors.danger} />
</View>
);
}
Now, in ListItem.js I want to render the ListItemDeleteAction.js as I have passed as a argument. Below in code I have described as comment.
Note: I am strict to this method, render the ListItemDeleteAction as it passed as argument, which is "DeleteIconView" as parameter in ListItem.js
function ListItem({ image, title, subTitle, ImageComponent, style, onPress, DeleteIconView}) {
return (
<TouchableHighlight
//onPress={onPress}
underlayColor={Colors.light}
>
<View style={[styles.container, style]}>
{ImageComponent}
{image && <Image style={styles.image} source={image} />}
<View style={styles.parentDeatailContainer}>
<View style={styles.detailContainer}>
<Text style={{ fontWeight: "bold" }}>{title}</Text>
{subTitle && <Text>{subTitle}</Text>}
</View>
<TouchableOpacity style={styles.deleteIconContainer} onPress={onPress}>
{DeleteIconView} /* This is the place where I want to render the
ListItemDeleteAction components as I passed as argument but How? */
</TouchableOpacity>
</View>
</View>
</TouchableHighlight>
);
}

You are passing the prop wrong. When you write DeleteIconView={ListItemDeleteAction}, you aren't actually creating a JSX component. This can be solved by writing the following.
renderItem={({ item }) =>
<ListItem style={styles.listItem}
title={item.title}
subTitle={item.description}
image={item.image}
DeleteIconView={<ListItemDeleteAction />}
onPress={() => handleDelete(item)}
/>
}
Now, the prop DeleteIconView is an actual JSX component which can be rendered as usual.

Related

How to show an icon on last index of flat list

I'm trying to wrap my flat list and trying to show an Icon after last index of Flatlist. I had tried but it works fine on a single row. when we data goes to next row it would not work.
Here is my flat list code. Modal and Input both are my custom component.
const renderItem = ({item}) => {
return (
<TouchableOpacity style={[styles.tagPostContainer, styles.viewTagContainer]}>
<AppText
type={'input'}
label={`#${item}`}
color={colors.placeholder}
containerStyle={[styles.tagPostInactiveTxt, styles.BgAddedTag]}
/>
</TouchableOpacity>
);
};
return(
<>
<View style={{flexDirection:'row',justifyContent:'flex-start'}}>
<FlatList
data={tags}
renderItem={renderItem}
keyExtractor={keyExtractor}
contentContainerStyle={styles.TagFlatlist}
/>
<TouchableOpacity
style={styles.plusIconContainer}
onPress={() => setVisible(true)}>
<CreateBuildIconFocus height={13} width={13} />
</TouchableOpacity>
</View>
<Modal
visible={visible}
buttonLabel={'Done'}
containerWidth={width / 1.7}
onCancel={onCancel}
onSubmit={onClick}
containerHeight={Platform.OS === 'android' ? 200 : 200}>
<Input
placeholder={'Add Tags'}
autoFocus={true}
minWidth={120}
maxWidth={150}
value={tag}
onChangeText={text => setTag(text)}
/>
</Modal>
</>
)
FlatList styles:
TagFlatlist: {
flexDirection: 'row',
flexWrap: 'wrap',
alignItems: 'center',
},
Here is my design screen.
I find a solution for this. You can implement ListFooterComponent that used for showing something on end of flatlist. Here you can see more details of ListFooterComponent.
Here are the code of Flatlist.
return(
<FlatList
data={tags}
renderItem={renderItem}
keyExtractor={keyExtractor}
ListFooterComponent={
<TouchableOpacity
style={styles.plusIconContainer}
onPress={() => setVisible(true)}>
<CreateBuildIconFocus height={13} width={13} />
</TouchableOpacity>
}
contentContainerStyle={styles.TagFlatlist}
/>
)

FlatList not rendering it showing anything other than FlatList

I was trying to render a list but it is not rendering if I try to render a text or an image it is rendering but the FlatList is not rendering this is the code that I have written
**
return(
<SafeAreaView forceInset={{ top: 'always' }} >
<Image
style={styles.tinyLogo}
source={require('../../assets/img.png')}
/>
<Text> checking </Text>
<FlatList
data={menu}
renderItem={(item) => {
return <Text>{item.name}</Text>
}}
keyExtractor={(item) => item.key }
/>
</SafeAreaView>
**
Update your renderItem to this
renderItem={({item}) => {
return <Text>{item.name}</Text>
}}

React Native Elements Handle ListItem click

I use React Native Elements library to create list items inside of a Flat List. I show a list of users and i need to handle style after a click.
My code is :
<View style={{flex: 1}}>
<FlatList
data={this.state.data}
renderItem={({item}) => (
<ListItem
leftAvatar={{source: {uri: item.avatar}}}
title={`${item.firstName} ${item.lastName}`}
// subtitle={item.email}
chevron
onPress={this.onItemClickHandler}
/>
)}
keyExtractor={item => item.email}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
<Button
title='Suivant'
onPress={() => navigation.navigate('LastStepToShare')}
containerStyle={{marginBottom: 15}}
/>
</View>
How can i edit the background of a clicked ListItem item ?
You could do something like this:
<FlatList
data={this.state.data}
renderItem={({item, index}) => {
const {selectedIndex} = this.state;
const itemStyle = selectedIndex === index ? styles.selected : styles.notSelected;
return (
<ListItem
leftAvatar={{source: {uri: item.avatar}}}
title={`${item.firstName} ${item.lastName}`}
style={itemStyle}
// subtitle={item.email}
chevron
onPress={() => this.onItemClickHandler(index)}
/>
)
}}
keyExtractor={item => item.email}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
and in your onItemClickHandler function, set the selectedIndex value in the state using this.setState.
Basically, get the selected index thanks to the onPress event and compare it to the current index from the renderItem function. Based on that, you can set a style variable.
Here is a sample code snippet, this might help you :
<FlatList
data={this.getAllTask()}
renderItem={({ item, index }) =>
<TouchableHighlight
onPress={() => {this.props.navigation.navigate('OtherPage', {text: item.task_name, index: index})}}>
<View style={styles.customRowContainer}>
<View style={styles.listContainer}>
<Image source={require('../Img/ic_task_icon.png')} style={styles.photo} />
<View style={styles.container_text}>
<Text style={styles.title}>
{item.task_name}
</Text>
<Text style={styles.description}>
ETA : {item.task_eta}
</Text>
</View>
</View>
</View>
</TouchableHighlight>}
keyExtractor={item => item.id}
/>
If you need to change the background color only while the item is pressed (ie. change back when the finger is up), you can customise underlayColor and activeOpacity of the underlying TouchableHighlight to achieve what you need:
<ListItem underlayColor="#ff0000" activeOpacity={1} title="Title" onPress={yourClickHandler} />
You can easily store the state of active Item, and set state on onItemClickHandler function, now you can change style according to state of item (is it active or not)
<View style={{ flex: 1 }}>
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<ListItem
style={this.state.active === item.id ? styles.active : null} //***
leftAvatar={{ source: { uri: item.avatar } }}
title={`${item.firstName} ${item.lastName}`}
// subtitle={item.email}
chevron
onPress={() => this.onItemClickHandler(item.id)}
/>
)}
keyExtractor={item => item.email}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
<Button
title='Suivant'
onPress={() => navigation.navigate('LastStepToShare')}
containerStyle={{ marginBottom: 15 }}
/>
</View>
and
this.onItemClickHandler(id) => {
this.setState({
active: id
})
}

React Native flatlist conditional rendering

I have the following flat list in react native with the following
items.
key
name
type
Now i also have the following renderItem function that is used to render
the elements of the flatlist.
renderItem={({ item }) => (
<View>
<View style={styles.navBarLeftButton}>
<Avatar
medium
rounded
source={{uri:item.name}}
activeOpacity={0.7}
onPress={() => console.log(this.state.data)}
/>
<Text style={styles.textbutton}>{item.type}</Text>
<Text>{item.description}</Text>
<Text>{item.request} <Emoji name={item.request} style={{fontSize: 15}} />
<Emoji name="pray" style={{fontSize: 15}} /></Text>
</View>
</View>
)}
I want to render a different render function base on the item key of the flatlist
Is there away i can do conditional rendering with react native flatlist base
on key?
The renderItem prop for Flatlist can accept 2 arguments, the second being index, so you can do something like
renderItem={({ item, index })=>{
if(index = 0){
//do something
}
}}
Then just throw in a switch or some if statements and you can render conditionally.
Based on 'theme' values in variable DATA (as keys) FlatList renderItem prop is conditionally accepting different Views/Components returned by separate functions
<FlatList
data={DATA}
renderItem={({ item, index }) => {
if (item.theme === 1) {
return this.renderTheme1({ item });
}
return this.renderTheme2({ item });
}}
keyExtractor={item => item.id}
/>
This works for me:
renderItem={({ item }) => (
item.isDeleted == false ?
<View>
<Activity isRunning={item.isRunning} />
</View>
: null
)}
keyExtractor={(item) => item.title}
/>
Are you looking to return two different template sets? Something like:
renderItem={({item, index}) => {
if (index == 0) {
return <View style={{flex: 1, flexDirection: 'row'}}>
<Image source={item.image} style={styles.flatList_imageView} resizeMode="contain"/>
</View>
}
return <View style={{flex: 1, flexDirection: 'row'}}>
<Text>{item.key}</Text>
</View>
}
I think it will help you
renderItem={({ item, index })=>
<View>
{index == 0 ? <Text>Some Text</Text> : <Text>Some Text</Text> }
</View>
}}

this2. is not a function

I'm getting the error "this2. is not a function"
I tried a few solution i found on google but still cant fun a way to call the function.
My main purpose is to call a action function in a action file. Had some issues so i plan to call a function first then try call that action.
viewJob(){
console.log("View");
}
renderItem({ item }) {
return(
<Card>
<View style={{height:300}}>
</View>
<View style={styles.detailWrapper}>
<Button
title="Apply"
onPress={() => this.viewJob()}
/>
</View>
</Card>
);
}
Update
render(){
return(
<View style={{ marginTop:10 }}>
<FlatList
contentContainerStyle={styles.list}
data={this.props.jobs}
keyExtractor={this._keyExtractor}
renderItem={this.renderItem.bind(this)} // I didnt bind this , which led to the error above
/>
</View>
);
}
You need to bind the method
render(){
return(
<View style={{ marginTop:10 }}>
<FlatList
contentContainerStyle={styles.list}
data={this.props.jobs}
keyExtractor={this._keyExtractor}
renderItem={this.renderItem.bind(this)}
/>
</View>
);
}
Note: if you use arrow function then you do not have to worry about binding
You can read more about when to bind from official doc