I can't wrap a FlatList, it makes the FlatList height is over the wrapper - javascript

Hello Everyone!
I want to display my notification data inside a Modal and using a FlatList, I am using react-native-modal for the Modal component, inside a Modal I have 3 main component like header, body, and footer.
header is just a title with the bottom line of it
body is a FlatList
and footer is a just Button for clear the notification
These 3 main components I wrap again with View component and I set the maxHeight for this (View) component
The body is the main issue here because the FlatList height is over the View height that I set the maxHeight, it's hard to explain and sorry, but you can see the picture at the bottom
And the important one is that I can't use flex:1 inside a Modal it's because a module that I use (react-native-modal) if I use flex: 1 it makes FlatList disappear
Picture
enter image description here
Code of ModalNotificationShowcase.jsx
import React, {
forwardRef,
memo,
useContext,
useEffect,
useImperativeHandle,
useState,
} from 'react';
import {View, Dimensions, Pressable, FlatList} from 'react-native';
import {Divider, Button, Icon, List} from '#ui-kitten/components';
import {IconHelper, Text, Modal} from '../Helper';
import {useRealmInstance, useRealmObjects} from '../../hooks';
import moment from 'moment';
import util from '../../utils';
import ThemeContext from '../../themes/ThemeContext';
const NotificationItem = memo(props => {
const {currentTheme} = props;
const [bgColor, setBgColor] = useState(
currentTheme === 'light' ? '#EDF1F7' : '#1A2138',
);
const notif = props.data;
const realm = props.realm;
return (
<Pressable
onPressIn={() =>
setBgColor(currentTheme === 'light' ? '#E4E9F2' : '#151A30')
}
style={{
padding: 12,
marginBottom: 12,
backgroundColor: bgColor,
borderRadius: 4,
}}
onPress={props.onPress}
onPressOut={() =>
setBgColor(currentTheme === 'light' ? '#EDF1F7' : '#1A2138')
}
>
<View style={{flexDirection: 'row'}}>
<IconHelper
color={notif.name === 'reminder' ? '#FF3D71' : '#0095FF'}
name={
notif.name === 'reminder'
? 'alert-triangle-outline'
: 'info-outline'
}
style={{marginRight: 8}}
onPress={() => console.log('Pressed')}
/>
<Text size={14} style={{flex: 1, marginBottom: 4}}>
{notif.message}
</Text>
</View>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<Text size={12} hint>
{moment(notif.createdAt).fromNow()}
</Text>
<View style={{flex: 1, alignItems: 'flex-end'}}>
<IconHelper
size={20}
color='#FF3D71'
name='trash-2-outline'
underlayColor='#E4E9F2'
onPress={() => {
realm.write(() => {
realm.delete(notif);
});
}}
/>
</View>
</View>
</Pressable>
);
});
const NotificationShowcase = props => {
const realm = useRealmInstance();
const notifications = useRealmObjects('notifications');
const {theme} = useContext(ThemeContext);
return (
<View
style={{
width: Dimensions.get('window').width - 48,
maxHeight: Dimensions.get('window').height - 48,
borderRadius: 4,
}}
>
// =====
// Header
// =====
<Text size={14} bold align='center' style={{padding: 12}}>
Notifikasi
</Text>
<Divider />
// =====
// Body
// =====
<View style={{padding: 12, flexGrow: 1, overflow: 'hidden'}}>
{notifications.isEmpty() ? (
<Text
size={14}
align='center'
hint
style={{
padding: 8,
marginBottom: 12,
backgroundColor: theme === 'light' ? '#EDF1F7' : '#1A2138',
borderRadius: 4,
}}
>
Belum ada notifikasi untuk saat ini
</Text>
) : (
// ======================
// The main issue is here
// ======================
<FlatList
data={notifications}
initialNumToRender={0}
maxToRenderPerBatch={1}
updateCellsBatchingPeriod={120}
numColumns={1}
keyExtractor={item => item._id.toString()}
renderItem={items => {
const notif = items.item;
return (
<NotificationItem
data={notif}
realm={realm}
currentTheme={theme}
/>
);
}}
/>
)}
// =====
// Footer
// =====
{!notifications.isEmpty() && (
<View
style={{
justifyContent: 'center',
alignItems: 'center',
}}
>
<Button
size='small'
appearance='outline'
accessoryLeft={props => (
<Icon {...props} name='trash-2-outline' />
)}
onPress={() => {
realm.write(() => {
realm.delete(notifications);
});
}}
>
Hapus semua
</Button>
</View>
)}
</View>
</View>
);
};
const ModalNotificationShowcase = forwardRef((props, ref) => {
let Modal_ref;
useImperativeHandle(ref, () => ({
show: () => Modal_ref.show(),
hide: () => Modal_ref.hide(),
}));
return (
<Modal
backdropStyle={{backgroundColor: 'rgba(9, 44, 76, .32)'}}
onBackdropPress={() => Modal_ref.hide()}
ref={refs => (Modal_ref = refs)}
>
<NotificationShowcase
navigate={props.navigate}
onPressNotifItem={() => Modal_ref.hide()}
/>
</Modal>
);
});
export default ModalNotificationShowcase;

Updated
const NotificationShowcase = props => {
return (
<View
style={{
flex: 1,
margin: 24,
borderRadius: 4,
}}
>
...
// =====
// Body
// =====
<View style={{flex: 1}}>
// ...
</View>
</View>
);
};

Related

Components display perfectly on web view but aren't being displayed on android view in React Native

I'm building an instagram clone using React Native with Homescreen consisting of custom Header and Imagepost components,but it isn't showing up properly on android although it displays perfectly on web view(images below).
I only added the Text and the Test Button for testing purposes
HomeScreen.js:
import React, { useEffect, useState } from "react";
import { View, Text, TouchableOpacity, Button } from "react-native";
import axios from "axios";
import ImagePost from "../../components/ImagePost";
import Header from "../../components/Header";
import Ionicons from "react-native-vector-icons/Ionicons";
import useStore from "../../store";
const HomeScreen = ({ navigation }) => {
const [posts, setposts] = useState([]);
const [current, setcurrent] = useState(null);
const user = useStore((state) => state.currentUser);
const setcurrentUser = useStore((state) => state.setcurrentUser);
useEffect(() => {
axios.get("http://localhost:5000/posts").then((response) => {
console.log(response.data.posts);
setposts(response.data.posts);
});
}, []);
return (
<View>
<Header navigation={navigation} />
<Text>huidhoasodhiohdp</Text>
<Button title="test" />
{console.log("now user", user)}
{console.log("posts", posts)}
{posts &&
posts.map((post) => {
return (
<View key={post._id}>
<ImagePost post={post} navigation={navigation} />
{console.log("This post is", post)}
</View>
);
})}
</View>
);
};
export default HomeScreen;
Header.js:
import React from "react";
import { View, TouchableOpacity, Text } from "react-native";
import Ionicons from "react-native-vector-icons/Ionicons";
import useStore from "../store";
const Header = ({ navigation }) => {
console.log("header navigation", navigation);
const user = useStore((state) => state.currentUser);
return (
<View
style={{
flex: 1,
flexDirection: "row",
justifyContent: "space-between",
backgroundColor: "white",
}}
>
<TouchableOpacity
onPress={() => navigation.navigate("AddScreen")}
style={{ margin: "5%" }}
>
<Ionicons name="add-outline" size={25} color="black" />
</TouchableOpacity>
{user && <Text>{user.username}</Text>}
{user && console.log(user.username)}
<TouchableOpacity style={{ margin: "5%" }}>
<Ionicons name="chatbubble-ellipses-outline" size={25} color="black" />
</TouchableOpacity>
</View>
);
};
export default Header;
ImagePost.js :
import React from "react";
import { View, Text, Image, TouchableOpacity, Button } from "react-native";
import Ionicons from "react-native-vector-icons/Ionicons";
const ImagePost = ({ post, navigation }) => {
return (
<View>
<View style={{ flex: 1, flexDirection: "row", alignItems: "center" }}>
<Image
style={{
width: 50,
height: 50,
borderRadius: 50,
marginRight: "3%",
}}
source={post.creator.pic}
/>
<Text style={{ fontWeight: "bold" }}>User</Text>
</View>
<View style={{ width: "100%", height: 450 }}>
<Image
style={{ resizeMode: "cover", height: "100%" }}
source={post.file}
/>
<View style={{ flex: 1, flexDirection: "row", marginBottom: "6%" }}>
<TouchableOpacity style={{ marginRight: "1%" }}>
<Ionicons name="heart-outline" size={25} color="black" />
</TouchableOpacity>
<TouchableOpacity
style={{ marginRight: "1%" }}
onPress={() =>
navigation.navigate("CommentsScreen", { postId: post._id })
}
>
<Ionicons name="chatbubble-outline" size={25} color="black" />
</TouchableOpacity>
</View>
<Text>
<Text style={{ fontWeight: "bold", marginRight: "5%" }}>
{post.creator.userName}
</Text>
{post.description}
</Text>
</View>
</View>
);
};
export default ImagePost;
Android view
Web view

data size bigger than 1 has rendering issue

data that worked looks like this
(I used JSON.stringify function to see how the data looks like)
[{"_id":"612e60c4ce136a1f4454c938", "individualPurchasePrice":9800,"teamPurchasePrice":640, "eventDealCategory":"DysonHairDryer"}]
below is the data that didn't work
[{"_id":"612e60c4ce136a1f4454c938", "individualPurchasePrice":9800,"teamPurchasePrice":640, "eventDealCategory":"JMWHairDryer"}, {"_id":"612e60c4ce136a1f4454c938", "individualPurchasePrice":9800,"teamPurchasePrice":640, "eventDealCategory":"JMWHairDryer"},]
this is the error message
Element type is invalid:expected a string (for built-in components) or a class/function (for composite components) but got: object.
import React from 'react'
import { SafeAreaView, View, Dimensions, Text, ScrollView } from 'react-native'
import ItemStore from '../stores/ItemStore'
import ImageManager from '../images/ImageManager'
import ItemListWithoutCategory from '../components/item/ItemListWithoutCategory'
import TimeDealItemComponent from '../components/item/TimeDealItemComponent'
const dims = Dimensions.get('window')
const TimeDealItemScreen = ({ route, navigation }) => {
const { eventDealCategoryName } = route.params
return (
<SafeAreaView style={{ flex: 1 }}>
<ScrollView style={{ height: 40, backgroundColor: 'red' }}>
<ImageManager
source='TimeDealGradientImage'
style={{
position: 'absolute',
width: '100%',
height: '100%',
top: 0,
bottom: 0,
left: 0,
right: 0,
}}
/>
<ItemListWithoutCategory
isFrom='TimeDealItemScreen'
ItemSeparatorComponent={<View style={{ height: 16 }} />}
ListFooterComponent={
<>
<View style={{ height: 16, backgroundColor: 'transparent' }} />
</>
}
data={ItemStore?.eventDealItems?.filter(
(item) => item.eventDealCategory === eventDealCategory,
)}
renderItem={({ item, index }) => (
<View style={{ paddingHorizontal: 8 }}>
<TimeDealItemComponent item={item} index={index} />
</View>
)}
ListFooterComponent={
<>
<View style={{ height: 16, backgroundColor: 'transparent' }} />
</>
}
/>
</ScrollView>
</SafeAreaView>
)
}
export default TimeDealItemScreen
import React, { useState, useRef, useEffect, useCallback } from 'react'
import { FlatList } from 'react-native'
import ItemStore from '../../stores/ItemStore'
import { observer } from 'mobx-react-lite'
import UserStore from '../../stores/UserStore'
import { useNavigation } from '#react-navigation/native'
import viewabilityConfig from '../config/viewabilityConfig'
const ItemListWithoutCategory = observer(
({
ListEmptyComponent,
ListFooterComponent,
ItemSeparatorComponent,
data,
renderItem,
ListHeaderComponent,
isFrom,
ref,
onEndReached,
numColumns,
}) => {
const navigation = useNavigation()
const onViewableItemsChanged = useCallback(
({ viewableItems, changed }) => {
changed.forEach((item) => {
if (item.isViewable) {
const addedImpressionItems = {
itemId: item.item?._id,
itemTitle: item.item?.itemTitle,
loggedAt: new Date(),
isFrom,
}
ItemStore.addImpressionItems(addedImpressionItems)
}
})
},
[ItemStore.screenOnFocusMyOrder],
)
const viewabilityConfigCallbackPairs = useRef([
{ viewabilityConfig, onViewableItemsChanged },
])
return (
<FlatList
ref={ref}
viewabilityConfigCallbackPairs={viewabilityConfigCallbackPairs.current}
data={data}
ListHeaderComponent={ListHeaderComponent}
renderItem={renderItem}
keyExtractor={(item, index) => item?._id + index.toString()}
ListEmptyComponent={ListEmptyComponent}
ListFooterComponent={ListFooterComponent}
ItemSeparatorComponent={ItemSeparatorComponent}
onEndReached={onEndReached}
numColumns={numColumns}
/>
)
},
)
export default ItemListWithoutCategory
import React, { useState, useEffect } from 'react'
import { View, TouchableOpacity, Dimensions } from 'react-native'
import BlackText from '../texts/BlackText'
import GrayText from '../texts/GrayText'
import BasicButton from '../buttons/BasicButton'
import { observer } from 'mobx-react-lite'
import UserStore from '../../stores/UserStore'
import OrderStore from '../../stores/OrderStore'
import ImageManager from '../../images/ImageManager'
import backendApis from '../../utils/backendApis'
import { useNavigation } from '#react-navigation/native'
import ItemStore from '../../stores/ItemStore'
import RedText from '../texts/RedText'
import FastImage from 'react-native-fast-image'
import ImageTextTimer from '../texts/ImageTextTimer'
import commaNumber from 'comma-number'
const dims = Dimensions.get('window')
const TimeDealItemComponent = observer(({ item, index }) => {
const FULL_GAGE_WIDTH = 70
const CURRENT_GAGE_WIDTH = item.stockSoldPercentage
const GAGE_HEIGHT = 16
const navigation = useNavigation()
const TRANSPARENT_GRAY_CIRCLE_SIZE = 80
const [eventDealStatusHere, setEventDealStatusHere] = useState(0)
const [orderRecord, setOrderRecord] = useState('unpurchased')
useEffect(() => {
const eventStartedDate = new Date(item.eventDealStartedAt) // x
const now = new Date().getTime() // y
const oneDayTerm = 1000 * 60 * 60 * 24 * 1 // 7일
const stockleft = item.eventDealStock - item.totalOrderQuantity
if (eventStartedDate > new Date(now)) {
setEventDealStatusHere('preOpened')
} else if (
eventStartedDate < new Date(now) &&
eventStartedDate > new Date(now - oneDayTerm) &&
stockleft > 0
) {
setEventDealStatusHere('opened')
} else if (
eventStartedDate < new Date(now) &&
eventStartedDate > new Date(now - oneDayTerm) &&
stockleft <= 0
) {
setEventDealStatusHere('temporarilyClosed')
} else setEventDealStatusHere('closed')
}, [])
useEffect(() => {
if (
OrderStore.loadedUserOrdersList.find(
(order) =>
[
'pre-shipping',
'shipping',
'exchanging',
'arrived',
'reviewed',
].includes(order.status) && item._id === order.itemInfo.itemId,
)
) {
setOrderRecord('purchased')
} else {
setOrderRecord('unpurchased')
}
}, [OrderStore.loadedUserOrdersList])
const StockInfoTextComponent = ({ text }) => {
return (
<View
style={{
flexDirection: 'row',
alignContent: 'center',
// backgroundColor: 'grey',
}}
>
<GrayText text={text} fontSize={14} dark numberOfLines={1} />
</View>
)
}
const StockInfoText = () => {
if (eventDealStatusHere === 'preOpened') {
return (
<StockInfoTextComponent
text={`${commaNumber(item.eventDealStock)}개 입고 예정`}
/>
)
}
if (eventDealStatusHere === 'temporarilyClosed') {
return <StockInfoTextComponent text='일시적 물량 소진' />
}
if (eventDealStatusHere === 'closed') {
return <StockInfoTextComponent text='재고 전량 소진' />
}
return <></>
}
return (
<View style={{ width: '100%' }}>
<View
style={{
flex: 1,
width: '100%',
}}
>
<TouchableOpacity
style={{
backgroundColor: 'white',
marginTop: 12,
padding: 8,
borderRadius: 8,
}}
activeOpacity={1.0}
onPress={() => {
if (ItemStore.isLoadingItemScreen) {
return
}
ItemStore.setIsLoadingItemScreen(true)
navigation.push('MainStackDItemScreen', {
itemId: item._id,
itemInfo: item.itemInfo,
enteringComponent: 'TimeDealItemComponent',
})
setTimeout(() => {
ItemStore.setIsLoadingItemScreen(false)
}, 1000)
}}
>
<View
style={{
flexDirection: 'row',
marginTop: 4,
borderRadius: 4,
}}
>
<View
style={{
flex: 2,
flexDirection: 'column',
paddingHorizontal: 8,
}}
>
<View
style={{
paddingBottom: 8,
flexDirection: 'row',
paddingRight: 16,
}}
>
<BlackText
text={item.itemTitle}
fontSize={16}
numberOfLines={2}
/>
</View>
{/* 1.아이템타이틀 끝 */}
{/* 7. 게이지 시작 */}
<View
style={{
alignContent: 'center',
justifyContent: 'center',
}}
>
{eventDealStatusHere === 'opened' && (
<View
style={{
flexDirection: 'row',
alignItems: 'center',
}}
>
<View
style={{
backgroundColor: '#E89FA1',
height: GAGE_HEIGHT,
width: FULL_GAGE_WIDTH,
borderRadius: 12,
}}
>
<View
style={{
backgroundColor: '#EC4F48',
height: GAGE_HEIGHT,
width: FULL_GAGE_WIDTH * CURRENT_GAGE_WIDTH,
borderRadius: 12,
}}
/>
</View>
{/* opened */}
{eventDealStatusHere === 'opened' && (
<View
style={{
flexDirection: 'row',
alignContent: 'center',
paddingLeft: 8,
// backgroundColor: 'grey',
}}
>
<GrayText
text={item.stockLeft}
fontSize={12}
numberOfLines={1}
/>
<GrayText
text='개 남음'
fontSize={12}
numberOfLines={1}
/>
</View>
)}
</View>
)}
</View>
{/* 7. 게이지 끝 */}
{orderRecord === 'purchased' && (
<View
style={{
borderRadius: 4,
paddingTop: 10,
}}
>
<>
<BasicButton
width={30}
text='이미 구매하신 아이템입니다.'
eventDealClosed
backgroundColor='#B3B4B7'
/>
</>
</View>
)}
</TouchableOpacity>
</View>
</View>
)
})
export default TimeDealItemComponent
below is the data that didn't work
[{"_id":"612e60c4ce136a1f4454c938", "eventDealCategory":"JMWHairDryer"}, {"_id":"612e60c4ce136a1f4454c938", "eventDealCategory":"JMWHairDryer"},]
It does not work in second example because instead of one object you have array of objects. To render them you need to map throught array.

How to save route.params with asyncstorage?

Srry if the title makes no sense. Don't know a better title.
How can I save route.params items that I pass to my second screen using AsyncStorage?
In my first screen i have a bunch of data in a FlatList that can be opened with a Modal. Inside that Modal I have a TouchableOpacity that can send the data thats inside the Modal to my second screen. The data that has been passed to the second screen is passed to a FlatList. The data in the FlatList should be saved to AsyncStorage. Tried alot of things getting this to work, but only getting warning message
undefined. Code below is the most recent progress.
Using React Navigation V5.
FIRST SCREEN
const [masterDataSource, setMasterDataSource] = useState(DataBase);
const [details, setDetails] = useState('');
<TouchableOpacity
onPress={() => {
const updated = [...masterDataSource];
updated.find(
(item) => item.id === details.id,
).selected = true;
setMasterDataSource(updated);
navigation.navigate('cart', {
screen: 'cart',
params: {
items: updated.filter((item) => item.selected),
},
});
setModalVisible(false);
}}>
<Text>Add to cart</Text>
</TouchableOpacity>
SECOND SCREEN
import React, { useEffect, useState } from 'react';
import { View, Text, FlatList, TouchableOpacity } from 'react-native';
import { useTheme } from '../Data/ThemeContext';
import AsyncStorage from '#react-native-async-storage/async-storage';
import Ionicons from 'react-native-vector-icons/Ionicons';
export default function ShoppingList({ route, navigation }) {
const [shoppingList, setShoppingList] = useState([]);
const { colors } = useTheme();
const todo = () => {
alert('Todo');
};
useEffect(() => {
restoreShoppingListAsync();
}, []);
const shoppingListAsync = () => {
const shoppingList = route.params && route.params.items;
setShoppingList(list);
storeShoppingList(list);
};
const asyncStorageKey = '#ShoppingList';
const storeShoppingListAsync = (list) => {
const stringifiedList = JSON.stringify(list);
AsyncStorage.setItem(asyncStorageKey, stringifiedList).catch((err) => {
console.warn(err);
});
};
const restoreShoppingListAsync = () => {
AsyncStorage.getItem(asyncStorageKey)
.then((stringifiedList) => {
console.log(stringifiedList);
const parsedShoppingList = JSON.parse(stringifiedList);
if (!parsedShoppingList || typeof parsedShoppingList !== 'object')
return;
setShoppingList(parsedShoppingList);
})
.then((err) => {
console.warn(err);
});
};
const RenderItem = ({ item }) => {
return (
<View>
<TouchableOpacity
style={{
marginLeft: 20,
marginRight: 20,
elevation: 3,
backgroundColor: colors.card,
borderRadius: 10,
}}>
<View style={{ margin: 10 }}>
<Text style={{ color: colors.text, fontWeight: '700' }}>
{item.name}
</Text>
<Text style={{ color: colors.text }}>{item.gluten}</Text>
<Text style={{ color: colors.text }}>{item.id}</Text>
</View>
</TouchableOpacity>
</View>
);
};
const emptyComponent = () => {
return (
<View style={{ alignItems: 'center' }}>
<Text style={{ color: colors.text }}>Listan är tom</Text>
</View>
);
};
const itemSeparatorComponent = () => {
return (
<View
style={{
margin: 3,
}}></View>
);
};
return (
<View
style={{
flex: 1,
}}>
<View
style={{
padding: 30,
backgroundColor: colors.Textinput,
elevation: 12,
}}>
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
<TouchableOpacity onPress={() => navigation.goBack()}>
<Ionicons name="arrow-back-outline" size={25} color="#fff" />
</TouchableOpacity>
<Text style={{ color: '#fff', fontSize: 20 }}>Inköpslista</Text>
<TouchableOpacity>
<Ionicons
name="trash-outline"
size={25}
color="#fff"
onPress={() => todo()}
/>
</TouchableOpacity>
</View>
</View>
<View style={{ flex: 1, marginTop: 30 }}>
<FlatList
data={shoppingList}
renderItem={RenderItem}
ListEmptyComponent={emptyComponent}
ItemSeparatorComponent={itemSeparatorComponent}
initialNumToRender={4}
maxToRenderPerBatch={5}
windowSize={10}
removeClippedSubviews={true}
updateCellsBatchingPeriod={100}
showsVerticalScrollIndicator={true}
contentContainerStyle={{ paddingBottom: 20 }}
/>
</View>
</View>
);
}
As you are using async storage to maintain the cart.
I would suggest an approach as below
Update the asyn storage when new items are added to or removed from the cart
Retrieve the items from the cart screen and show the items there
Before you navigate store the items like below
AsyncStorage.setItem(
'Items',
JSON.stringify(updated.filter((item) => item.selected))
).then(() => {
navigation.navigate('Cart', {
items: updated.filter((item) => item.selected),
});
});
The cart screen would be something like below
function Cart({ navigation, route }) {
const [data,setData]=useState([]);
React.useEffect(() => {
async function fetchMyAPI() {
const value = await AsyncStorage.getItem('Items');
setData(JSON.parse(value));
}
fetchMyAPI();
}, []);
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button title="Go back" onPress={() => navigation.goBack()} />
<FlatList
data={data}
renderItem={RenderItem}
/>
</View>
);
}
Working Example
https://snack.expo.io/#guruparan/cartexample

How to search mapped list in react native

I have been finding it very difficult to search a mapped list in react native. Actually, doing that with a Flatlist would be very easy for me, but this is really giving me a headache. I hope someone will be able to help me out.
So, the code looks like this
import React, { Component, useState } from 'react';
import { Button, Animated, Share, ScrollView,
ImageBackground, StyleSheet, View} from "react-native";
import { Container, Header, Content, ListItem, Item, Input, Text, Icon, Left, Body, Right, Switch } from 'native-base';
const Auslawpart = ({ route, navigation}) => {
const {parts, hereme} = route.params;
const [search, setSearch] = useState('');
const [filteredDataSource, setFilteredDataSource] = useState(parts);
const filterSearch = (text) => {
const newData = parts.filter((part)=>{
const itemData = part.name.toUpperCase()
const textData = text.toUpperCase()
return itemData.indexOf(textData)>-1
});
setFilteredDataSource(newData);
setSearch(text);
}
return (
<Container>
<Animated.View
style={{
transform:[
{translateY:translateY }
],
elevation:4,
zIndex:100,
}}
>
<View style={{
// marginTop:Constant.statusBarHeight,
position:"absolute",
top:0,
left:0,
right:0,
bottom: 0,
height: 50,
backgroundColor:"#f0f0f0",
borderBottomWidth: 1,
borderBottomColor: '#BDC3C7',
flexDirection:"row",
justifyContent:"space-between",
elevation: 4,
}}>
<View style={{margin: 10, flex: 1 }}>
<TouchableOpacity onPress={() => navigation.goBack()}>
<Icon type="MaterialIcons" name="arrow-back" style={{ left: 10, }}
size={50} />
</TouchableOpacity>
</View>
<View style={{
justifyContent:"space-around",
margin: 4,
flex: 1,
marginLeft:0,
}}>
<Text numberOfLines={3} style={{fontSize:10,
alignSelf: 'flex-end', color:"#212F3C",
padding: 2}}>{hereme}</Text>
</View>
</View>
</Animated.View>
<Content style={{marginTop:50}}>
<Item>
<Icon type= "MaterialIcons" />
<Input placeholder="Search legal terms and maxisms"
onChangeText={(text) => filterSearch(text)}
/>
<Icon type="Octicons" name="law" />
</Item>
{parts.map((part) => (
<TouchableOpacity
key={part.name}
>
<ListItem onPress={() =>
navigation.navigate("Auslawcount", {
meaning: part.meaning,
partname: part.name})
}>
<Icon type="Octicons" name="law" />
<Body>
<Text onScroll={(e)=>{
scrollY.setValue(e.nativeEvent.contentOffset.y)
}} style={{ fontSize: 17, fontFamily: "Lato-Regular",}} key={part.name}>{part.name.toUpperCase()}</Text>
</Body>
</ListItem>
</TouchableOpacity>
))}
</Content>
</Container>
);
};
export default Auslawpart;
The data in part.name are passed from another screen to this screen. I am try to make the Input field search through the mapped part.name. can anybody please help me with a solution.
Here is an Example
snack: https://snack.expo.io/#ashwith00/bold-waffles
const data = [
{ name: 'Suleman' },
{ name: 'Sulan' },
{ name: 'Suljan' },
{ name: 'Ram' },
{ name: 'Raj' },
];
const Auslawpart = ({ route, navigation }) => {
const {} = route.params;
const [filteredDataSource, setFilteredDataSource] = useState(parts);
const filterSearch = (text) => {
if (text.length > 0) {
const newList = data.filter((part) => {
const name = part.name.toUpperCase();
const textData = text.toUpperCase();
return name.includes(textData);
});
setFilteredDataSource(newList);
} else {
setFilteredDataSource(parts);
}
};
return (
<View>
<TextInput placeholder="Enter here" onChangeText={filterSearch} />
<ScrollView>
{filteredDataSource.map((item, i) => (
<Text key={i} style={{ paddingVertical: 30 }}>
{item.name}
</Text>
))}
</ScrollView>
</View>
);
};

expo camera show black screen for first time : React-Native

I have Created Project with expo-camera which on click of button opens camera. However first time when i click that button only black screen is render, after reopening the screen, and clicking the same button, the Camera UI is render on Screen.
Problem
I don't know why it show black screen first. The Problem only exist in android devices.
Link to Expo Snack Try this example on android devices.
import React, { useState, useEffect, useContext } from 'react';
import {
SafeAreaView,
View,
Text,
Dimensions,
ImageBackground,
Image,
Alert,
} from 'react-native';
import { Camera } from 'expo-camera';
import { Entypo, Ionicons, FontAwesome } from '#expo/vector-icons';
import { Surface, Button, TextInput } from 'react-native-paper';
const { width, height } = Dimensions.get('window');
let cameraRef;
const PickImage = ({ navigation }) => {
const [hasPermission, setHasPermission] = useState(null);
const [type, setType] = useState(Camera.Constants.Type.back);
const [isCameraUiOn, setIsCameraUiOn] = useState(false);
const [isCapturing, setIsCapturing] = useState(false);
const [flashMode, setFlashMode] = useState(true);
const [capturePhoto, setCapturePhoto] = useState(null);
const snap = async () => {
if (cameraRef) {
let photo = await cameraRef.takePictureAsync({
quality: 0.5,
});
setCapturePhoto(photo.uri);
setIsCapturing(false);
setIsCameraUiOn(false);
}
};
const getCameraPermission = async () => {
const { status } = await Camera.requestPermissionsAsync();
setHasPermission(status === 'granted');
};
useEffect(() => {
getCameraPermission();
}, []);
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
if (isCameraUiOn) {
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<Camera
style={{ flex: 1 }}
type={type}
ref={(ref) => (cameraRef = ref)}
flashMode={
flashMode
? Camera.Constants.FlashMode.on
: Camera.Constants.FlashMode.off
}>
<Entypo
name="cross"
color="#FFF"
size={50}
onPress={() => setIsCameraUiOn(false)}
/>
<View
style={{
flex: 1,
backgroundColor: 'transparent',
display: 'flex',
justifyContent: 'space-evenly',
alignItems: 'flex-end',
flexDirection: 'row',
zIndex: 9999,
}}>
<Ionicons
name="md-reverse-camera"
color="#FFF"
size={35}
onPress={() => {
setType(
type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back
);
}}
/>
{isCapturing ? (
<FontAwesome name="circle" color="#FFF" size={60} />
) : (
<FontAwesome
name="circle-o"
color="#FFF"
size={60}
onPress={() => {
setIsCapturing(true);
snap();
}}
/>
)}
<Ionicons
name="ios-flash"
color={flashMode ? 'gold' : '#FFF'}
size={35}
onPress={() => setFlashMode(!flashMode)}
/>
</View>
</Camera>
</View>
</SafeAreaView>
);
} else {
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={{ margin: 20 }}>
<Text
style={{
fontSize: 25,
fontWeight: '600',
}}>
Report Cattles with Ease !!
</Text>
<Text
style={{
marginVertical: 10,
}}>
Our System uses, cloud based fancy image detection algorithm to
process your image.
</Text>
</View>
<View
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
}}>
<Button
style={{
width: width * 0.5,
}}
icon="camera"
mode="contained"
onPress={() => setIsCameraUiOn(true)}>
Press me
</Button>
</View>
</SafeAreaView>
);
}
};
export default PickImage;
Link to snack Expo
im with the same problem rn, some people suggested asking for permission before rendering

Categories

Resources