I've been going back and forward with this thing for a week now and can't get to a solution with it. Basically I want to remove something from firebase database but the thing is that I don't know what key is. So I added a server timestamp which should be a unique thing and now I would like to find that timestamp in the database and remove that child/node, however u call this, to which that timestamp belongs.
This part creates views with the info from the database and when I would click on that image I would like to remove it from the database.
<View style={styles.itemsList}>
{this.props.items.map((item, index) => {
if (item.ttype == 0) {
return (
<View key={index} style={styles.viewHolderNegative}>
<TouchableOpacity onPress={() => this.removeSelected(item.timestamp)}>
<Image source={require('./assets/remove24.png')}></Image>
</TouchableOpacity>
<Text style={styles.textTransaction}>{item.name}</Text>
<Text style={[styles.textTransaction, { fontSize: 20 }]}>{item.date}</Text>
</View>
);
} else if (item.ttype == 1) {
return (
<View key={index} style={styles.viewHolderPositive}>
<TouchableOpacity onPress={() => this.removeSelected(item.timestamp)}>
<Image source={require('./assets/remove24.png')}></Image>
</TouchableOpacity>
<Text style={styles.textTransaction}>{item.name}</Text>
<Text style={[styles.textTransaction, { fontSize: 20 }]}>{item.date}</Text>
</View>
);
}
})}
</View>
I assume that you are aware of firebase methods, if not then check firebase docs for react-native,
you can achieve removing an item by remove() method but you will have to acknowledge which item to remove.
for that, you will have to give key in child(key) method.
see this,
firebase.database().ref('ITEMS').child('KEY').remove();
ITEMS is the collection name and KEY is your timestamp.
Related
// renderItem
<View>
<Image source={image} style={{position: 'absolute', zIndex: 40}} />
</View>
<View>
<ImageBackground source={image} style={{position: 'absolute', zIndex: 50}}/>
<Image source={image} style={{position: 'absolute', zIndex: 30}} />
<Image source={image} style={{position: 'absolute', zIndex: 20}} />
</View>
<FlatList renderItem={renderItem}/>
Idea is that the code above FlatList is fixed in place and image in renderItem can change position with scroll.
Expected Behavior
renderItem is stacked between zIndex of 50 and 30.
Current Behavior
renderItem is always at the back (before zIndex 20 eventhough renderItem has a zIndex of 40)
What I tried
For testing, I added another Image tag between 50 and 30 in the same file and that seems to be working. So I am guessing the issue only happens when componentizing it. I also tried messing with elevation since my target is Android but to no effect.
Any insight would be really helpful - thank you!
Working with zIndex sometimes happens this. For your case, I suggest you use the props ListHeaderComponent and stickyHeaderIndices to sticky the header when scrolling the list.
// Some code...
const Header = () => (
<View style={styles.header}>
<ImageBackground
style={styles.imageBackground}
source={require('./assets/image.png')}
>
<Text style={styles.headerTitle}>Fixed header</Text>
</ImageBackground>
</View>
);
// More code...
return (
<FlatList
ListHeaderComponent={Header}
stickyHeaderIndices={[0]}
data={DATA}
renderItem={renderItem}
keyExtractor={item => item.id}
/>
)
I create a snack on Expo for you to see the complete example. Just scan the QR Code from your smartphone.
I am using a react-native-gesture-handler library with reanimated and react-native-redash. I want to make scrollView scrollable which is nested inside panGestureHandler but all the interactions are handled by panGestureHandler, so scrollView is not working. Here is my code.
VideoModal.js file
import Animated , {useCode , cond , eq , set , add, block, interpolate, Extrapolate} from "react-native-reanimated"
import {PanGestureHandler , State } from "react-native-gesture-handler"
import {usePanGestureHandler , useValue , timing , snapPoint} from "react-native-redash/lib/module/v1"
export default function VideoModal(props) {
const { video } = props;
const {gestureHandler , velocity , translation , state} = usePanGestureHandler()
const translateY = useValue(0)
const offsetY = useValue(0);
const snapPoints = snapPoint(translateY , velocity.y , [0 ,upperBound])
useCode(()=>block([
cond(
eq(state , State.ACTIVE),
[
set(translateY , add(offsetY , translation.y))
]
),
cond(
eq(state , State.END),
[
set(translateY , timing({from:translateY , to:snapPoints, duration:350})),
set(offsetY , translateY)
]
)
]))
return (
<>
<View
style={{
height: statusBarHeight,
backgroundColor: 'black',
}}
/>
<PanGestureHandler {...gestureHandler} >
<Animated.View
style={{
...shadow,
transform:[{translateY:translateY}],
zIndex:10
}}
>
<TouchableWithoutFeedback onPress={()=>alert('Working'}>
<View style={{ backgroundColor: 'white', width }}>
<View style={{ ...StyleSheet.absoluteFillObject }}>
<PlayerControls title={video.title} onPress={() => alert('abc')} />
</View>
<AnimatedVideo
source={video.video}
style={{ width, height:videoContent }}
resizeMode={Video.RESIZE_MODE_COVER}
shouldPlay
/>
</View>
</TouchableWithoutFeedback>
<Animated.View style={{ backgroundColor: 'white', width:contentWidth, height:contentHeight }}>
<Animated.View style={{opacity:contentOpacity}}>
**<VideoContent {...{ video }} />**
</Animated.View>
</Animated.View>
</Animated.View>
</PanGestureHandler>
</>
);
}
the scrollView is inside VideoContent
import {
View, StyleSheet, Text, Image, ScrollView,
} from 'react-native';
export default function VideoContent(props) {
const { video } = props;
return (
<ScrollView>
<View style={styles.upNext}>
<Text style={styles.upNextTitle}>Up next</Text>
{
videos.map(v => (
<View key={v.id} style={styles.thumbnail}>
<Image source={v.thumbnail} style={styles.thumbnailImage} />
<View style={styles.thumbnailContent}>
<Text numberOfLines={2} style={styles.thumbnailTitle}>{v.title}</Text>
<Text style={styles.thumbnailUsername}>{v.username}</Text>
</View>
</View>
))
}
</View>
</ScrollView>
);
}
Is there anyway I can tell pangesture to work only if the finger is placed on the top part of screen otherwise it should not work and i can scroll the content present inside the scrollview??
Hey i Know its bit late to reply to your answer but i also faced the similar issue, a bit of research unable to me find this trick
activeOffsetX={[-10, 10]}
in you pangestureHandler like this
<PanGestureHandler
onGestureEvent={onGestureEvent}
activeOffsetX={[-10, 10]}
onHandlerStateChange={evt =>handleStateChange(evt)}
>
source : https://www.gitmemory.com/issue/software-mansion/react-native-gesture-handler/1380/786721032
I hope it helps
Actually my question is about React Native, but i think it's similar to React.
I'm tried to create dynamic menu with loop in array like this:
My question is: how do I conditionally add another <View/> while using map?
let say there's 4 value in array and I've tried to do something like this:
_renderMenu(){
let menu = this.state.menu.map((el, index)=>{
if(index==0){
return(
<View style={{flex:1, margin:5, borderRadius:5, backgroundColor:Color.amber_200}}/>
)
} else {
//Wrap the rest with <View style={MyStyle}>
return(
<View style={{flex:1, margin:5, borderRadius:5, backgroundColor:Color.amber_200}}/>
)
//</View>
}
})
return(
<View style={{flex:1, padding:5}}>
{menu}
</View>
)
}
My loop pattern something like this:
<View style={{flex:1, margin:5, borderRadius:5, backgroundColor:Color.amber_200}}/>
<View style={{flexDirection:'row', flex:1}}> //if index!==0 wrap the rest with this view
<View style={{flex:1, margin:5, borderRadius:5, backgroundColor:Color.amber_200}}/>
<View style={{flex:1, margin:5, borderRadius:5, backgroundColor:Color.amber_200}}/>
<View style={{flex:1, margin:5, borderRadius:5, backgroundColor:Color.amber_200}}/>
</View>
Is it possible to conditionally something like my case?
Based on the above comments, here's a solution for your problem:
First, you'll need to add lodash to the project to use the _.chunck method: https://lodash.com/docs/4.17.11#chunk
_renderMenu() {
const menuItem = (item, index) => (
<View key={`menu_item_${index}`} style={{ flex: 1, margin: 5, borderRadius: 5, backgroundColor: Color.amber_200 }}>{item}</View>
)
const splitArray = _.chunk(this.state.menu.slice(1), 3)
return (
<View style={{ flex: 1, padding: 5 }}>
{menuItem(this.state.menu[0], 0)}
{
splitArray.map((array, index) => {
return (
<View style={{ flexDirection: 'row', flex: 1 }}>
{array.map((element, elementIndex) => menuItem(element, (elementIndex * index) + elementIndex + 1))}
</View>
)
})
}
</View>
)
}
the splice will skip the specified number of elements, in our case, the first one. We will render the first menu item alone, then will render the other items.
Now for the key, i'm trying to keep it unique using the * + formula to generate them based on both indexes.
I have 8 buttons which i would like to align in horizontal row, side by side. everything i have tried hasn't worked and the just display one on top of another.
Here's what i have at the mo.
Thanks
categories: ['art', 'funny', 'inspire', 'life', 'love', 'management', 'sports', 'students'],
render() {
let cat = this.state.categories.map((value, key) => {
return (
<View style={styles.catButtons}>
<TouchableOpacity
style={styles.buttonContainer}
key={key}
activeOpacity={0.7}
>
<Button style={styles.button}
color={'darkslategrey'}
key={key}
title={value}
onPress={() => { this.getCategoryQuote(value) }}
/>
</TouchableOpacity>
</View>
)
})
return (
<View>
{cat}
</View>
)
}
const styles = StyleSheet.create({
catButtons: {
flexWrap: 'wrap'
},
buttonContainer: {
width: 125,
margin: 10
},
});
I think, in this case, the flex items are the buttons. But the problems lies in the flex container: TouchableOpacity.
As your code suggest, there is one flex container for one button, and that is repeated by the map function.
It should be one flex container for all flex items (buttons). That means, the flex container should be outside of your map function and the items directly as its children (that are mapped by the map function).
createTableFL(){
var { isLoading, tableData } = this.state;
return(
<ScrollView style={{marginTop:10}} >
<ScrollView horizontal={true}>
<View style={styles.containerT}>
<FlatList
data={tableData}
style={{flex:1,marginVertical:20}}
keyExtractor={(x,i)=>i}
renderItem={({item,i}) =>
{
<View>
<Text>{item.inventory_id}</Text>
<Text>{item.created_on}</Text>
</View>
}}
numColumns={1}
/>
</View>
</ScrollView>
</ScrollView>
)
}
set column number like this :numColumns={2}
Please check https://aboutreact.com/example-of-gridview-using-flatlist-in-react-native/ link for reference.
else you just change the number of columns of your table by assign value to numColumns={number of columns you want}.
Hope this works for you.