Hide and show component on pulling down the screen - react-native

I am trying to show a search bar on pulling down the screen and hiding it on scroll the view up.
Below is my react-native code:
render() {
return (
<View style={styles.container}>
<ScrollView
style={styles.scrollView}
onScroll={() => { console.log('onMomentumScrollBegin'); }}
onScrollBeginDrag={() => { console.log('onScrollBeginDrag'); }}
onScrollEndDrag={() => { console.log('onScrollEndDrag'); }}
>
<SearchBar
onChangeText={(obj) => {console.log(obj);}}
placeholder='Type Here...'
icon={{ type: 'font-awesome', name: 'search' }}
/>
<View style={styles.innerContainer}>
<Text>Hello</Text>
</View>
<View style={styles.innerContainer}>
<Text>Hello</Text>
</View>
</ScrollView>
</View>
);
}
onScroll, onScrollBeginDrag, onScrollEndDrag is not calling if there are not enough elements for scroll.
Here is screenshot of my screen:
If anyone has any idea about how to achieve it, that will be very helpful.
Thanks in advance.

Related

Correct way to use memo in Flatlist react native

Good evening everyone .
I have created the following Flatlist :
<View style={{ flex: 1 }}>
<FlatList
ListFooterComponent={
loadMore && page < pageMax ? (
<ActivityIndicator color={Colors.grey40} />
) : (
<View />
)
}
ListFooterComponentStyle={{ height: 200 }}
contentContainerStyle={styles.listExercise}
keyExtractor={() => uuid.v4()}
data={exercises}
renderItem={renderItemRE}
removeClippedSubviews={true}
onEndReached={() => {
setOnEndReachedCalledDuringMomentum(true);
}}
onMomentumScrollEnd={loadMoreFc}
onEndReachedThreshold={0.3}
ListEmptyComponent={
<Text contentW B18>
Nessuna Esercizio presente
</Text>
}
/>
</View>
This is renderItem function
const renderItemRE = ({ item }) => {
return (
<RenderItemRE
selectables={route.params?.selectables}
item={item}
navigation={navigation}
/>
);
};
And finally this is my component RenderItemRE
const RenderItemRE = ({ item, navigation, selectables }) => {
return (
<View style={styles.globalContainer}>
<TouchableOpacity
style={styles.touchable}
onPress={() => {
navigation.navigate(Routes.InfoEsercizio, {
id_ex: item.id,
nomeEx: item.nome,
});
}}
>
<View style={styles.container}>
<Image
indicator={Progress}
style={styles.img}
source={{
uri: item.galleria
? item.galleria[0]
? item.galleria[0]
: "logo"
: ApiConstants.DEFAULT_IMAGE,
}}
/>
<Text
style={[
customtext(DYNAMIC_FONTS_SIZE.FONT_SIZE_BIG).regular,
styles.nameStyle,
]}
>
{item.nome}
</Text>
</View>
</TouchableOpacity>
</View>
);
};
function arePropsEqual(prevProps, nextProps) {
return nextProps.item.id === prevProps.item.id;
}
export default memo(RenderItemRE, arePropsEqual);
This is a correct way to use memo in react native ? Or am I doing something wrong? I'm noticing that when the list gets bigger the rendering slows down. I was wondering what was the correct way to optimize. Thank you in advance

How to Send data from from one components flat-list to another component in react native

Categories.js
<FlatList
data={categorylist}
keyExtractor={(item, index) => item.tc_id}
vertical
numColumns={4}
renderItem={({ item, index }) => {
return (
<Pressable onPress={subcat}>
<View style={styles.catLayout}>
<View style={styles.imageLayout}>
<Image source={{ uri: item.image }} style={styles.image}
/>
</View>
<Text style={styles.productname}>
{item.name != null ? item.name : ""}
</Text>
<Text>{item.uuid}</Text>
</View>
</Pressable>
);
}}
/>
I am getting data from categorylist array , i am displaying a bunch of items of categories here , i want show different sub-categories depending on each items "uuid".
I want to send the {item.uuid} to subcategories screen and reuse it in there.
As you are displaying the data on the view using flatlist you have onPress after clicking on any item you just need to send the data
Screen (A)
<FlatList
data={categorylist}
keyExtractor={(item, index) => item.tc_id}
vertical
numColumns={4}
renderItem={({ item, index }) => {
return (
<Pressable onPress={() => navigation.navigate('subcategories',{uuid:item.uuid}) }>
<View style={styles.catLayout}>
<View style={styles.imageLayout}>
<Image source={{ uri: item.image }} style={styles.image}
/>
</View>
<Text style={styles.productname}>
{item.name != null ? item.name : ""}
</Text>
<Text>{item.uuid}</Text>
</View>
</Pressable>
);
}}
/>
Screen (B)
you can get it like this
class component
constructor(props) {
super(props);
this.state = {
uuID: this.props.navigation.state.params.uuid,
}
}
functional component
const Subcategory = (props) => {
const [uUID, setuUID] = useState(props.route.params.uuid);

Bottom Sheet doesn't close when navigating to different screen

I'm new to programming and when I navigate to the new screen and the bottom sheet doesn't close here's the picture of it. I'm using #gorhom/bottom-sheet^4.I have done some research and I know that using useFocusEffect could acheive it but i dont really know how. Can someone help me on this?
<BottomSheetModal
enablePanDownToClose={true}
ref={bottomSheetModalRef}
index={0}
snapPoints={snapPoint}
backdropComponent={renderBackdrop}
>
<View>
<TouchableWithoutFeedback
onPress={() => {
navigation.navigate("Settings");
}}
>
<Text style={styles.modalText}>Settings</Text>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback
onPress={() => {
navigation.navigate("Saved");
}}
>
<Text style={styles.modalText}>Saved</Text>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback
onPress={() => {
navigation.navigate("Delete");
}}
>
<Text style={styles.modalText}>Delete</Text>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={() => {}}>
<Text style={styles.modalText}>Log out</Text>
</TouchableWithoutFeedback>
</View>
</BottomSheetModal>
There are few ways to do it. Here are two:
Add useFocusEffect that runs when your screen with BottomSheetModal is unfocused:
useFocusEffect(
React.useCallback(() => {
return () => bottomSheetRef.current?.close()
}, [])
);
Close BottomSheetModal, whenever you are leaving your screen. In order to do that, you have to call bottomSheetModalRef.current?.close while navigating:
<TouchableWithoutFeedback
onPress={() => {
navigation.navigate("Settings");
bottomSheetModalRef.current?.close();
}}
>
<Text style={styles.modalText}>Settings</Text>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback
onPress={() => {
navigation.navigate("Saved");
bottomSheetModalRef.current?.close();
}}
>
<Text style={styles.modalText}>Saved</Text>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback
onPress={() => {
navigation.navigate("Delete");
bottomSheetModalRef.current?.close();
}}
>
<Text style={styles.modalText}>Delete</Text>
</TouchableWithoutFeedback>
If you're using React Navigation you can also automatically close any open modals whenever navigation changes like so:
import { useBottomSheetModal } from '#gorhom/bottom-sheet'
const Navigation = () => {
const { dismissAll: dismissAllModals } = useBottomSheetModal()
return <NavigationContainer
onStateChange={() =>
dismissAllModals()
}>
{...}
</NavigationContainer>
}

function not passed with required variable (Expo/React Native)

I am trying to let allow the button to navigate me to the Home Screen after pressing, but it seems like the function does not have the variable 'navigation', how do I pass this variable to the function? Below is my code snippet
const LoggedInPage = props => {
return (
<View style={styles.container}>
<Text style={styles.loggedin}>Welcome: {props.name}</Text>
<Image style={styles.image} source={{ uri: props.photoUrl }} />
<TouchableOpacity style={styles.button2} onPress={() => this.props.navigation.navigate('Home')}>
<Text style={styles.buttonText}>Get Started!</Text>
</TouchableOpacity>
</View>
)
}
There is no this binding in functional component; you can use useNavigation hook to get the navigation prop.
Code:
const LoggedInPage = ({ name, photoUrl }) => {
const navigation = useNavigation();
return (
<View style={styles.container}>
<Text style={styles.loggedin}>Welcome: {name}</Text>
<Image style={styles.image} source={{ uri: photoUrl }} />
<TouchableOpacity style={styles.button2} onPress={() => navigation.navigate('Home')}>
<Text style={styles.buttonText}>Get Started!</Text>
</TouchableOpacity>
</View>
)
}

How to access specific index of FlatList in react native

I am populating a FlatGrid from API. Each grid has an icon which is by default green color. I want to change the color of a specific icon when pressed. But as of now after pressing the icon, the color of all the icons are changing. Can anyone suggest what needs to be done? Attaching the code for reference. After pressing the icon green color should turn into blue.
constructor(props){
super(props);
this.state={
isLoading: true,
dataSource: null,
color:'green'
}
}
colorChange(color)
{
if(color=='green')
{
this.setState({
color:'blue'
})
}
else
{
this.setState({
color:'green'
})
}
}
render(){
if(this.state.isLoading){
return (
<View style={styles.container}>
<ActivityIndicator size="large" />
</View>
)
}else{
console.log(this.state.dataSource)
return(
<ScrollView>
<FlatGrid
itemDimension={130}
items={this.state.dataSource}
style={styles.gridView}
renderItem={({ item, index }) => (
<View style={{borderWidth:1,borderStyle:'dashed',borderRadius:1,width:120,height:50,flexDirection:'row'}}>
<Text style={{fontSize:20,paddingLeft:10}}>{item.Name}</Text>
<Icon
name="car"
size={30}
key={item.Name}
style={{color:(item.Status=='Available'?this.state.color:'grey'),paddingLeft:20,backgroundColor:'white'}}
onPress={this.colorChange.bind(this.state.color)}
/>
</View>
)}
keyExtractor={item => item.Name}
/>
</View>
You can do an array of colors but that's not a good practice.
The other solution is to handle the renderItem as a functional component since that's how it works.
Like this
renderItem={({ item, index }) => {
const [color, setColor] = React.useState('green')
return(
<View style={{borderWidth:1,borderStyle:'dashed',borderRadius:1,width:120,height:50,flexDirection:'row'}}>
<Text style={{fontSize:20,paddingLeft:10}}>{item.Name}</Text>
<Icon
name="car"
size={30}
key={item.Name}
style={{color:(item.Status=='Available'?color:'grey'),paddingLeft:20,backgroundColor:'white'}}
onPress={() => setColor('blue')}
/>
</View>
)}}