Components renders under another component - reactjs

My Tag Component, which consist out of rendered texts and a text input component, renders under another component, my button and behaves super weird.
If you look at the gif you can also see, that the tags from the second line onwards are not getting wrapped by my container style as well.
I made a gif, which should make it easier to see :)
http://www.giphy.com/gifs/JmD2VWAXU3S12LQ0Ya
const styles = StyleSheet.create({
textInput: {
flex: 1,
borderRadius: 8,
paddingLeft: 9,
paddingRight: 9,
height: 30,
marginRight: 15,
},
tagContainer: {
flexDirection: 'row',
flexWrap: 'wrap'
},
tags: {
backgroundColor: "#9AA5B1",
borderRadius: 8,
paddingLeft: 9,
paddingRight: 9,
paddingTop: 4,
paddingBottom: 4,
marginRight: 10,
marginBottom: 4,
flexDirection: "row",
},
text: {
color: "white",
},
container: {
backgroundColor: '#F5F7FA',
borderRadius: 8,
paddingLeft: 9,
paddingRight: 9,
height: 30,
marginRight: 15,
flexDirection: "row",
flexWrap: "wrap",
},
});
renderTags1 = (tag, index, deleteTag) => {
return (
<TouchableOpacity
onPress={index => deleteTag(index)}
style={styles.tags}
key={`${tag}-${index}`}
>
<Text style={styles.text}>{tag}</Text>
</TouchableOpacity>
);
};
const InputTags = ({ tags, value, onChangeText, deleteTag }) => {
return (
<View style={styles.container}>
<View style={styles.tagContainer}>
{tags.map((tag, index) => {
return this.renderTags1(tag, index, deleteTag);
})}
</View>
<TextInput
style={styles.textInput}
placeholder="Outdoor"
onChangeText={text => onChangeText({ text })}
value={value}
autoCorrect={false}
multiline={true}
/>
</View>
);
};
export { InputTags };
For my Button :
import React from 'react';
import { Text, TouchableOpacity, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
view: {
backgroundColor: '#E12D39',
width: 280,
height: 50,
justifyContent: 'center',
alignSelf: 'center',
borderRadius: 10,
marginTop: 40,
marginBottom: 40,
},
text: {
alignSelf: 'center',
fontFamily: 'OpenSans-Semibold',
fontSize: 22,
color: 'white',
},
});
const SearchButton = ({ onPress, text }) => {
return (
<TouchableOpacity style={styles.view} onPress={onPress}>
<Text style={styles.text}>{text}</Text>
</TouchableOpacity>
);
};
export { SearchButton };
Expected behavior is for the Button to go down. Tried to remove every single flex property, but could not quite figure it out yet

seems like the height is not increasing when it wraps, could confirm it by making the container bg a different color
Looks like you hard coded the height to be 30, which is probably causing the bug

Related

Cannot select an item from autocomplete when there is button or text input behind the item

I cannot click the 1st and 2nd item because there is text input behind it and 3rd and 4th item because of the button behind it. 5th item is clickable. I tried using zindex but it does not work. I am using react-native-autocomplete-input library.
It works fine in iOS but not in Android
This is my code
import Autocomplete from 'react-native-autocomplete-input';
import {
GestureHandlerRootView,
TouchableOpacity as Touchable,
} from 'react-native-gesture-handler';
<View style={[styles.inputContainer, globalStyles.zIndex1]}>
<Text style={styles.inputLabel}>{getSupplierLabel()}</Text>
<Autocomplete
editable={true}
autoCorrect={false}
data={filteredParties}
onChangeText={(text: string) => {
//some code
}}
value={party}
flatListProps={{
keyboardShouldPersistTaps: 'always',
keyExtractor: (party: any) => party.id,
renderItem: ({item: {name}}: any) => (
<Touchable
style={[globalStyles.margin10, globalStyles.zIndex1]}
onPress={() => {
setFilteredParties([]);
setParty(name);
}}>
<Text textColor={color.gray}>{name}</Text>
</Touchable>
),
}}
inputContainerStyle={globalStyles.borderWidth0}
listContainerStyle={styles.autocompleteListContainerStyle}
containerStyle={styles.textInput}
/>
const styles = StyleSheet.create({
inputContainer: {
flexDirection: 'row',
alignItems: 'center',
marginTop: 10,
},
textInput: {
flex: 2,
borderWidth: 1,
borderColor: color.gray,
borderRadius: 2,
marginLeft: 5,
},
autocompleteListContainerStyle: {
left: 0,
position: 'absolute',
right: 0,
top: 41,
zIndex: 1,
},
});
Wrap your AutoComplete component with a view and give it a suitable zIndex :
import Autocomplete from 'react-native-autocomplete-input';
import {
GestureHandlerRootView,
TouchableOpacity as Touchable,
} from 'react-native-gesture-handler';
<View style={[styles.inputContainer, globalStyles.zIndex1]}>
<Text style={styles.inputLabel}>{getSupplierLabel()}</Text>
<View style={ zIndex: 2 }>
<Autocomplete
editable={true}
autoCorrect={false}
data={filteredParties}
onChangeText={(text: string) => {
//some code
}}
value={party}
flatListProps={{
keyboardShouldPersistTaps: 'always',
keyExtractor: (party: any) => party.id,
renderItem: ({item: {name}}: any) => (
<Touchable
style={[globalStyles.margin10, globalStyles.zIndex1]}
onPress={() => {
setFilteredParties([]);
setParty(name);
}}>
<Text textColor={color.gray}>{name}</Text>
</Touchable>
),
}}
inputContainerStyle={globalStyles.borderWidth0}
listContainerStyle={styles.autocompleteListContainerStyle}
containerStyle={styles.textInput}
/>
</View>
const styles = StyleSheet.create({
inputContainer: {
flexDirection: 'row',
alignItems: 'center',
marginTop: 10,
},
textInput: {
flex: 2,
borderWidth: 1,
borderColor: color.gray,
borderRadius: 2,
marginLeft: 5,
},
autocompleteListContainerStyle: {
left: 0,
position: 'absolute',
right: 0,
top: 41,
zIndex: 1,
},
});

TypeError: undefined is not an object (evaluating '_this.showActionSheet')

I'm working on building a random app using react-native.
I'm trying to create an action sheet that activates via a button but I keep getting this error.
when I first run the app it works fine, but when I reload the app again I get this error every time.
I tried to use and many other things I found online but got the same result.
please help, I'm new to react-native :(
import React from 'react';
import {Text, View, StyleSheet, TextInput, TouchableOpacity, Button} from 'react- native';
import ActionSheet from 'react-native-actionsheet'
//----------------------------
showActionSheet = () => {
this.ActionSheet.show()
}
//----------------------------
TouchableOpacity.defaultProps = { activeOpacity: 0.8 };
const AppButton = ({ onPress, title }) => (
<TouchableOpacity onPress={onPress} style={styles.appContainer}>
<Text style={styles.appButtonText}>{title}</Text>
</TouchableOpacity>
);
const forgotpassword = () => {
return (
<View>
<Text style={{fontSize: 20, color: '#000', fontWeight: '200', alignSelf: "center", marginTop: 70,}}> Forgot Password? </Text>
<Text style={{fontSize: 15, color: '#B8B8B8', fontWeight: '100', marginLeft: 20, marginTop: 40,}}> Email address </Text>
<TextInput style={styles.inputpassword} secureTextEntry={true}/>
<AppButton
title= 'Continue'
/>
<View style={{fontSize: 20, fontWeight: '100', color: '#B8B8B8', alignSelf: "center", bottom: 90,}}>
<Text onPress={this.showActionSheet}>Contact Support</Text>
<ActionSheet
ref={o => this.ActionSheet = o}
title={'Which one do you like ?'}
options={['Mail', 'Gmail', 'Outlook', 'Yahoo Mail', 'Cancel']}
cancelButtonIndex={2}
destructiveButtonIndex={1}
onPress={(index) => { /* do something */ }}
/>
</View>
</View>
);
};
export default forgotpassword;
const styles = StyleSheet.create({
inputpassword: {
opacity: 0.5,
width: "90%",
borderWidth: 1,
borderRadius: 10,
padding: 7,
marginBottom: 160,
alignSelf: "center",
borderColor: "#B8B8B8",
},
appContainer: {
elevation: 8,
width: "90%",
backgroundColor: "#FABB51",
alignSelf: "center",
padding: 7,
borderRadius: 10,
paddingVertical: 10,
bottom: 120,
paddingHorizontal: 12,
},
appButtonText: {
fontSize: 18,
color: "#fff",
fontWeight: "bold",
alignSelf: "center",
},
});
Place your showActionSheet function inside the forgotpassword component and instead of this.ActionSheet, use useRef() like this:
const actionSheet = useRef();
const showActionSheet=()=>{
actionSheet.current.show()
}
and on your ActionSheet do like:
<ActionSheet ref={actionSheet} .../>
And please use PascalCase to name your components.

React Native how to create a delete button that deletes a different element as well as itself

Look at my code below please I am trying to find a way to make a delete button but i am very new to react native, i have been trying to do it for the past few hours.
import React, { useState } from 'react';
import { StyleSheet, FlatList, Text, View, Image, TextInput, Button, Keyboard, TouchableOpacity, CheckBox } from 'react-native';
import Interactable from 'react-native-interactable';
export default function App()
const [enteredGoal, setEnteredGoal] = useState('');
const [courseGoals, setCourseGoals] = useState([]);
const goalInputHandler = (enteredText) => {
setEnteredGoal(enteredText);
};
const addGoalHandler = () => {
if (enteredGoal.length > 0) {
setCourseGoals(currentGoals => [...currentGoals, enteredGoal])
} else {
alert("You have to write something!")
}
}
return (
<View style={styles.container}>
<View style={styles.topPart}></View>
<View style={styles.navBar}>
<Image source={require('./assets/baseline_menu_black_18dp.png/')} />
<Text style={styles.heading}> Grocery List </Text>
</View>
<View style={styles.body}>
<TextInput
style={styles.textInput}
placeholder='Groceries'
maxLength={20}
onBlur={Keyboard.dismiss}
value={enteredGoal}
onChangeText={goalInputHandler}
/>
<View style={styles.inputContainer}>
<TouchableOpacity style={styles.saveButton}>
<Button title="ADD" onPress={addGoalHandler} color="#FFFFFF" style={styles.saveButtonText} />
</TouchableOpacity>
</View>
<View style={styles.container}>
<FlatList
data={courseGoals}
renderItem={itemData => (
<View style={styles.groceryItem} >
<Text style={styles.groceryItemText}>{itemData.item}</Text>
<Text style={styles.groceryItemDelete}>X</Text>
</View>
)}
/>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
topPart: {
height: '3%',
backgroundColor: '#5498A7',
},
navBar: {
height: '10%',
backgroundColor: '#5498A7',
elevation: 3,
paddingHorizontal: 15,
flexDirection: 'row',
alignItems: 'center',
},
body: {
backgroundColor: '#edebe9',
height: '100%',
flex: 1
},
heading: {
fontWeight: "bold",
justifyContent: 'center',
paddingLeft: '13%',
fontSize: 25,
color: '#d6d4d3'
},
textInput: {
borderColor: '#CCCCCC',
borderTopWidth: 1,
borderBottomWidth: 1,
height: 50,
fontSize: 25,
paddingLeft: 20,
paddingRight: 20
},
saveButton: {
borderWidth: 1,
borderColor: '#5498A7',
backgroundColor: '#5498A7',
padding: 15,
margin: 5,
},
saveButtonText: {
color: '#FFFFFF',
fontSize: 20,
textAlign: 'center'
},
groceryItem: {
borderWidth: 1,
borderColor: 'black',
backgroundColor: '#6A686B',
padding: 15,
margin: 5,
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between'
},
groceryItemText: {
color: '#d6d4d3',
},
groceryItemDelete: {
color: 'red',
fontWeight: 'bold',
fontSize: 20
}
});
I hope you guys can find a solution I will keep u guys updated on my progress, I am constantly looking for answers but i don't really understand how to make the delete (X) work and to make it delete a different element, if you know a way to make work better just let me know i would appreciate it a lot
You have to send index to delete function.
renderItem={(itemData,index) => (
<View style={styles.groceryItem} >
<Text style={styles.groceryItemText}>{itemData.item}</Text>
<Text style={styles.groceryItemDelete.bind(index)}>X</Text>
</View>
and example delete function :
groceryItemDelete(index){
setCourseGoals(currentGoals.splice(index,1))
}
You need to implement the delete method and add an onPress event:
renderItem={(itemData, idx) => (
<View style={styles.groceryItem} >
<Text style={styles.groceryItemText}>{itemData.item}</Text>
<Text style={styles.groceryItemDelete} onPress={() => deleteItem(idx)}>X</Text>
</View>
)}
const deleteItem = idx => {
const clonedGoals = [...courseGoals]
clonedGoals.splice(idx, 1)
setCourseGoals(clonedGoals)
}

Keyboard Avoiding View Shrinking

I would like my page to scroll up so that the user can correctly type its email and password. Therefore, I am using KeyboardAvoidingView.
However, when I use it, it shrinks my textinput picture instead of moving up the page. Without the keyboard my app looks like this picture.
My code following for this page :
export default class LoginScreen extends React.Component {
constructor(props) {
super(props)
}
state = {
email: '',
password: ''
}
handleEmail = (text) => {
this.setState({ email: text })
}
handlePassword = (text) => {
this.setState({ password: text })
}
render() {
return (
<View style={styles.container}>
<ImageBackground source={require('../pics/main.png')} style={styles.background}>
<KeyboardAvoidingView behavior="padding" style={{ flex: 1}} >
<Text style={styles.title2}>WELCOME</Text>
<TextInput
style={styles.inputEmail}
placeholder="Enter Email"
onChangeText={this.handleEmail}
/>
<TextInput
style={[styles.inputEmail, styles.inputPassword]}
placeholder="Enter password"
onChangeText={this.handlePassword}
/>
<View style={styles.buttons}>
<TouchableOpacity style={styles.login} onPress={() => this.props.navigation.navigate('MainScreen')} >
<Text style={styles.loginText}>LOGIN</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.login} onPress={() => this.props.navigation.navigate('SignUpScreen')}>
<Text style={styles.loginText}>SIGN UP</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</ImageBackground>
</View>
);
}
}
const styles = StyleSheet.create({
area: {
flex: 1
},
container: {
flex: 1,
},
background: {
flex: 1,
resizeMode: "cover",
width: '100%',
height: '100%'
},
title2: {
paddingTop: 10,
color: color.primary,
fontSize: 25,
alignSelf: 'center',
justifyContent: 'flex-start'
},
inputEmail: {
borderWidth: 2,
borderColor: color.primary,
borderRadius: 10,
width: '50%',
height: '5%',
marginTop: 100,
alignSelf: 'center',
backgroundColor: color.secondary
},
inputPassword: {
marginTop: 10
},
buttons: {
flexDirection: 'row',
justifyContent: 'space-around',
marginTop: 30,
marginLeft: 70,
marginRight: 70,
},
login: {
borderColor: color.primary,
borderRadius: 20,
borderWidth: 2,
width: '40%',
height: '118%',
backgroundColor: color.primary
},
loginText: {
alignSelf: 'center',
marginTop: 5,
marginBottom: 1,
color: 'white'
}
});
Any idea on what I am doing wrong ?
UPDATE : to avoid shrinking put the text input container width and height not as a percentage but as real numbers : inputEmail --> width: 200, height: 35,
Here is a solution with your code, I have fixed this in this snack with your provided code.
Expo Snack with CSS fixes to avoid keyboard

React Native Text Component not rendered

I am a newbie in react native. I tried to create a to-do app, simple enough. But I have no idea why the text in the created to-do item not rendered
import React, { useState } from 'react';
import {
StyleSheet,
Text,
View,
Button,
TextInput,
FlatList,
Dimensions
} from 'react-native';
export default function App() {
const [task, setTaskText] = useState('')
const [tasks, setTasks] = useState([])
const addTask = () => {
setTasks([...tasks, { key: Math.random().toString(), text: task}])
}
return (
<View style={styles.container}>
<View style={styles.form}>
<TextInput
onChangeText={setTaskText}
value={task}
placeholder="Type a task..."
style={styles.input}
multiline
/>
<Button title="Add Task" style={styles.button} onPress={addTask} />
</View>
<FlatList
style={styles.itemContainer}
data={tasks}
renderItem={itemData => (
<View style={styles.taskItem}>
<Text style={styles.taskText}>{itemData.text}</Text><Button title="Complete" />
</View>
)}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop: 32,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
form: {
// flex: 1,
flexDirection: 'row',
padding: 32,
justifyContent: 'space-between',
},
button: {
fontSize: 32,
padding: 5
},
tasks: {
flex: 1,
alignContent: 'flex-start',
},
input: {
flex: 1,
fontSize: 22,
},
itemContainer: {
flex: 1,
width: Dimensions.get('window').width,
padding: 20,
borderColor: 'red',
borderWidth: 1
},
taskItem: {
padding: 10,
borderColor: 'black',
borderWidth: 1,
backgroundColor: '#efefef',
marginBottom: 10,
alignContent: 'center',
justifyContent: 'center',
flexDirection: 'row'
},
taskText: {
flex: 1,
fontSize: 24,
borderColor: 'yellow',
borderWidth: 1,
color: 'black',
textAlign: 'left'
}
});
So I tried to use a flat list and gave some border color to pin point the component rendered. I could see that the text component was rendered but there is no content
Can anyone help? What went wrong?
Your implementation was wrong.
It should be renderItem({item, index, separators})
And for each of the item you should consume it like item.text
<FlatList
style={styles.itemContainer}
data={tasks}
renderItem={ ({item}) => (
<View style={styles.taskItem}>
<Text style={styles.taskText}>{item.text}</Text><Button title="Complete" />
</View>
)}
/>

Resources