in my program write in react native i have this snippet:
getCompanyFunction() {
const { enterprises, navigation } = this.props;
return (
<ScrollView horizontal>
<View style={{ display: 'flex', flexDirection: 'row', flexWrap: 'nowrap' }}>
{ enterprises.map((enterprise) => {
return (
<Card key={enterprise.id} containerStyle={{ width: Dimensions.get('window').width - 50 }}>
<ListItem
title={enterprise.name}
subtitle={(
<View>
<Text style={{ color: theme.text.default }}>
{enterprise.fonction}
</Text>
<Text style={{ color: theme.palette.text.default }}>
{enterprise.location || ''}
</Text>
</View>
)}
onPress={enterprise.id && (() => handleItemPress(enterprise.id, navigation))}
/>
</Card>
);
})}
</View>
</ScrollView>
);
}
for my example i have three enterprise but only the first is apparent in the result. However the map function should iterate my array?
thank!
The map function returns a new array with the results of its operation.
MDN docs:
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
You could use a FlatList component to render the resulting array from your map function.
Here's an example on how you could do it (assuming you don't need to alter enterprises data):
renderCard = (enterprise) => {
return (
<Card key={enterprise.id} containerStyle={{ width: Dimensions.get('window').width - 50 }}>
<ListItem
title={enterprise.name}
subtitle={(
<View>
<Text style={{ color: theme.text.default }}>
{enterprise.fonction}
</Text>
<Text style={{ color: theme.palette.text.default }}>
{enterprise.location || ''}
</Text>
</View>
)}
onPress={enterprise.id && (() => handleItemPress(enterprise.id, navigation))}
/>
</Card>
);
}
getCompanyFunction()
const { enterprises, navigation } = this.props;
return (
<ScrollView horizontal>
<View style={{ display: 'flex', flexDirection: 'row', flexWrap: 'nowrap' }}>
<FlatList
data={enterprises}
renderItem={({ item }) => renderCard(item)} />
</View>
</ScrollView>
);
}
You don't necessarily need to use a component to render a list of components, but it's usually the best course of action to do so.
Related
My app displays images and other info getting data from a JSON, and I want to set a blurRadius on the selected image when the unblur function is called.
My code is the following:
const [blur, setBlur] = useState(160);
const unblur = () => {
if(blur == 160){
setBlur(0);
}
}
{isLoading ? <ActivityIndicator/> : (
<FlatList
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => (
<>
<Text style={{ textAlign: "left", color: 'white', fontSize: 24 }}>
<Image style={{ alignSelf: "center" }} source={{uri: item.profile_picture, width: 48, height: 48}} />
{item.username}
</Text>
<TouchableOpacity onPress={() => unblur()}>
<Image style={{ alignSelf: "center" }} blurRadius={blur} source={{uri: item.picture, width: 400, height: 320}} />
</TouchableOpacity>
<Text style={{ textAlign: "left", color: 'white', fontSize: 24 }}>
ID {item.id}
</Text>
<Text>
{'\n'}{'\n'}
</Text>
</>
)}
/>
)}
I want to change the {blur} value for a given image when I tap the TouchableOpacity component of the image I want to unblur. Right in this moment when I tap an image, all the images in the list are getting unblurred.
You should add the blur values inside your items like this. Create a new components called Items. Then, add the blur state inside it. (not inside Main).
const Main = () => {
if (isLoading) {
return;
<ActivityIndicator />;
}
return (
<FlatList
data={data}
keyExtractor={({ id }, index) => id}
renderItem={({ item }) => <Item item={item} />}
/>
);
};
const Item = ({ item }) => {
const [blur, setBlur] = useState(160);
const unblur = () => {
if (blur == 160) {
setBlur(0);
}
};
return (
<>
<Text style={{ textAlign: "left", color: "white", fontSize: 24 }}>
<Image
style={{ alignSelf: "center" }}
source={{ uri: item.profile_picture, width: 48, height: 48 }}
/>
{item.username}
</Text>
<TouchableOpacity onPress={() => unblur()}>
<Image
style={{ alignSelf: "center" }}
blurRadius={blur}
source={{ uri: item.picture, width: 400, height: 320 }}
/>
</TouchableOpacity>
<Text style={{ textAlign: "left", color: "white", fontSize: 24 }}>
ID {item.id}
</Text>
<Text>
{"\n"}
{"\n"}
</Text>
</>
);
};
Also, may I suggest you can use 'onPressIn'. That way, image will unblur when the finger tap the image, not press the image. But that was your decision.
I am quite new to react native. I have created a FlatList for rendering this list of items, however, it is not scrolling. I've googled it for hours and tried nearly everything suggested in stack overflow threads - removed flex, added flex, wrapped it in a view, but nothing seems to work.
Here is my code (the issue is in the second FlatList) -
return(
<View style = {{ height: '100%' }}>
<View style = {{ width: '100%' }}>
<AppHeader />
</View>
<View style = {{ width: '100%'}}>
<View style = {{ width: '70%', alignSelf: 'center', flex: 1 }}>
<View>
<FlatList
data = {this.getTodayDay()}
renderItem = {this.renderItemDays}
keyExtractor = {this.keyExtractor}
/>
</View>
<FlatList
data = {this.getVisibleHours()}
renderItem = {this.renderItem}
keyExtractor = {this.keyExtractor}
scrollEnabled = {true}
/>
</View>
</View>
</View>
this.renderItem -
renderItem = () => {
// irrelevant code
if( isClass === true ){
return(
<ListItem bottomDivider = {true} style = {styles.renderItemActiveClass}>
<ListItem.Content>
<TouchableOpacity
onPress = {()=>{
this.props.navigation.navigate('ClassDetailsScreen', { "data": classData })
}}>
<ListItem.Title>{ definiteClassTime }</ListItem.Title>
<ListItem.Subtitle>{ classData.class_name }</ListItem.Subtitle>
</TouchableOpacity>
</ListItem.Content>
</ListItem>
)
}
else{
return(
<ListItem bottomDivider = {true} style = {styles.renderItemClass}
containerStyle = {styles.renderItemContent}>
<ListItem.Content>
<ListItem.Title>{item}:00</ListItem.Title>
<ListItem.Subtitle>No Class</ListItem.Subtitle>
</ListItem.Content>
</ListItem>
)
}
}
the StyleSheet -
renderItemClass: {
borderColor: 'purple',
borderWidth: 2
},
renderItemActiveClass: {
borderColor: 'green',
borderWidth: 2
},
renderItemContent: {
},
Could somebody please tell me what I'm doing wrong?
Add a height to both the flatlist. And also wrap your second flatlist within a seperate view. Here is an example:
return (
<View style={{ height: "100%" }}>
<View style={{ width: "100%" }}>
<AppHeader />
</View>
<View style={{ width: "100%" }}>
<View style={{ width: "70%", alignSelf: "center", flex: 1 }}>
<View style={{ height: 60, alignSelf: "center" }}>
<FlatList
data={this.getTodayDay()}
renderItem={this.renderItemDays}
keyExtractor={this.keyExtractor}
/>
</View>
<View style={{ height: 60, alignSelf: "center" }}>
<FlatList
data={this.getVisibleHours()}
renderItem={this.renderItem}
keyExtractor={this.keyExtractor}
scrollEnabled={true}
/>
</View>
</View>
</View>
</View>
);
As title says, I need to create a modal popup for every list item for the selected sizes to be displayed. I'm using the react-native-popup-dialog but without results. Could you help me? Here's my code:
step1 = () => {
return (
<View style={{ flex: 8}}>
<Text h3 style={{ ...styles.title, marginVertical: 10.0 }}>{this.state.user=="User"?"Size":"CargoSize"}</Text>
<ScrollView>
<View style={{ marginHorizontal: 16.0 }}>{
this.state.size.map((l, i) => (
<ListItem key={i} onPress={() => this.setState({sizeSelected: i, sizeName: l.title, sizeId: l.id})} underlayColor='transparent'
containerStyle={{backgroundColor: this.state.sizeSelected==i?'#F76858':'white', borderWidth: 1.0,
borderColor: '#707070', marginBottom: 10.0, paddingVertical: 5.0, paddingHorizontal: 40.0}}>
<ListItem.Content>
<View style={{
flexDirection: 'row', alignItems: 'center',
justifyContent: 'center'
}}>
<Text style={styles.textSize}>{l.title}</Text>
<Text style={{ fontSize: 16 }}>{l.example}</Text>
</View>
</ListItem.Content>
</ListItem>
))
}</View>
</ScrollView>
</View>
);
}
I believe you can declare a single modal in your list component and show or hide the modal when the user presses the listItem. Also, make the pressed item active and pass the item to your modal so that the modal can show the details of the active item.
App.js
export default function App() {
const [modalVisible, setModalVisible] = React.useState(false);
const [activeItem, setActiveItem] = React.useState(null);
const onPress = (item) => {
setActiveItem(item)
setModalVisible(true)
}
const renderItem = ({ item }) => (
<TouchableOpacity onPress={()=>onPress(item)}>
<Item title={item.title} />
</TouchableOpacity>
);
return (
<View style={styles.container}>
<FlatList
data={DATA}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
<Popup modalVisible={modalVisible} setModalVisible={setModalVisible} activeItem={activeItem} />
</View>
);
}
Modal.js
export default function Popup({modalVisible, setModalVisible, activeItem}) {
return (
<View style={styles.centeredView}>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
}}>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalText}>{activeItem?.title}</Text>
<TouchableHighlight
style={{ ...styles.openButton, backgroundColor: '#2196F3' }}
onPress={() => {
setModalVisible(!modalVisible);
}}>
<Text style={styles.textStyle}>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
</View>
);
}
Here is a working demo for you.
I made something similar in my react-native project and do this:
Made with {useState} the variables i need in my modal, example, the name of my component
Wrap the ListItem component in a Pressable component
Put the onPress={() => {//Put your code here}} function, inside you will put the SetVariable of the variable you want in the modal
The Pressable will update the variable with the wich you want in the modal
I am working on a simple React Native e-commerce app and i ran into a issue. I am trying to add the option to change the language, and it has worked so far with the Redux but now i need to dynamically change the sidebar menu and I cant because it is hardcoded as a prop.The code for the menu is this.
const ShopNavigator = createDrawerNavigator(
{
Produktetee: ProductsNavigator,
Rezervimet: OrdersNavigator,
Postoni: AdminNavigator},
{
contentOptions: {
activeTintColor: MyColors.primary
},
contentComponent: props => {
const {log_out} = useSelector(state => state.language)
const dispatch = useDispatch();
return (
<View style={{ flex: 1, paddingTop: 50 }}>
<SafeAreaView forceInset={{ top: "always", horizontal: "never" }}>
<DrawerItems {...props} />
<Button
title={log_out}
color={MyColors.primary}
onPress={() => {
dispatch(authActions.logOut());
// props.navigation.navigate("Auth");
}}
/>
<View style={{flexDirection: 'row'}}>
<View style={{flex:1 , marginRight:10, marginTop: 5,}} >
<Button
title="English"
type="outline"
color={MyColors.primary}
onPress={()=>{
dispatch(index.selectLanguage(languages.english))
}}
/>
</View>
<View style={{flex:1, marginTop: 5,}} >
<Button
title="Shqip"
type="outline"
color={MyColors.primary}
onPress={()=>{
dispatch(index.selectLanguage(languages.albanian))
}}
/>
</View>
</View>
</SafeAreaView>
</View>
);
}
}
);
I am trying to use the hook, but I can't. If somebody could help me I would be very grateful.
I have some data in my firestore. The structure is :
User -> DocId(Some id)-> name(String), number(String), friends (array)
I got the friends array and i append to my local array data. Now when i render in the flat list. Its not showing. But same temp data which i created locally its working fine. I check my array data count after i fetch from firestore. Its showing correct count. But not able to display the data in flat list.
My code :
import firebase from '#react-native-firebase/app';
import firestore from '#react-native-firebase/firestore';
UserArray =[]
export default class HomeScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
UserArray: [],
}
}
componentWillMount() {
firebase.firestore().doc(`User/${'beQVEcfLsXV8JhA8L2SDDq03bmD3'}`)
.get()
.then(doc => {
this.setState({UserArray: doc.data().friends})
})
}
renderPost = post => {
return (
<View style={styles.feedItem}>
<Feather name="book" style={styles.avatar} size={30}/>
<View style={{ flex: 1 }}>
<View style={{ flexDirection: "row", justifyContent: "space-between", alignItems: "center" }}>
<View>
<Text style={styles.name}>{post.name}</Text>
<Text style={styles.timestamp}>{post.name} | {post.name}</Text>
</View>
</View>
</View>
<Feather name="chevron-right" style={{color: "#808080", alignSelf: 'center'}} size={20}/>
</View>
);
};
render() {
return (
<View style={styles.container}>
{
UserArray.length ?
(<FlatList
style={styles.feed}
data={UserArray}
keyExtractor={(index) => index.toString()}
renderItem={({ item }) => this.renderPost(item)}
// keyExtractor={item => item.id}
showsVerticalScrollIndicator={false}
></FlatList>) :
(
<View style={{ width: '70%', alignSelf: 'center',justifyContent: 'center' , alignItems: 'center', marginTop: '20%'}}>
<Feather name="smile" color="#009387" size={40}/>
<Text style={{paddingTop: 20, textAlign: 'center', fontSize: 15, fontWeight: 'bold', color: '#A9A9A9'}}>Hey folk, You dont' have any friends list</Text>
</View>
)
}
</View>
);
}
}
In my screen i am always getting. You don't have any data.
But in componentDidMount() after i fetch data from firestore. Inside my then :
.then(doc => {
alert(UserArray.length);
})
Its showing correct array count. Here is my friends array :
{
"name": "quaroe",
"number": "3940904",
friends: [
{
"name": "alber"
},
{
"name": "romea"
},
{
"name": "basea"
}
]
}
my doubt is that render is called before componentDidMount. But i tried componentWillMount. And i added alert. Always render called first and then only componentWillMount or componentDidMount is getting called
Put your UseArray in the state instead. I believe the flatlist is not showing anything because when it is rendered your firebase function is not yet completed so UseArray is empty. And render cant detect changes of your constant UseArray that why it's not showing any list even if your fetch is succesful.
try this
import firestore from '#react-native-firebase/firestore';
export default class HomeScreen extends React.Component {
constructor(props) {
super(props);
this.state = {
userArray: [],
};
}
componentDidMount() {
firebase
.firestore()
.doc(`User/${'beQVEcfLsXV8JhA8L2SDDq03bmD3'}`)
.get()
.then(doc => {
this.setState({userArray: doc.data().friends});
});
}
renderPost = post => {
return (
<View style={styles.feedItem}>
<Feather name="book" style={styles.avatar} size={30} />
<View style={{flex: 1}}>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
}}>
<View>
<Text style={styles.name}>{post.name}</Text>
<Text style={styles.timestamp}>
{post.name} | {post.name}
</Text>
</View>
</View>
</View>
<Feather
name="chevron-right"
style={{color: '#808080', alignSelf: 'center'}}
size={20}
/>
</View>
);
};
render() {
return (
<View style={styles.container}>
{this.state.userArray && this.state.userArray.length > 0 ? (
<FlatList
style={styles.feed}
data={this.state.userArray}
keyExtractor={index => index.toString()}
renderItem={({item}) => this.renderPost(item)}
// keyExtractor={item => item.id}
showsVerticalScrollIndicator={false}
/>
) : (
<View
style={{
width: '70%',
alignSelf: 'center',
justifyContent: 'center',
alignItems: 'center',
marginTop: '20%',
}}>
<Feather name="smile" color="#009387" size={40} />
<Text
style={{
paddingTop: 20,
textAlign: 'center',
fontSize: 15,
fontWeight: 'bold',
color: '#A9A9A9',
}}>
Hey folk, You dont' have any friends list
</Text>
</View>
)}
</View>
);
}
}