export default class AchieveScreen extends ValidationComponent{
constructor(props) {
super(props)
this.state = {
visible: false,
filter: 1,
date: new Date(),
selected: new Date(),
loaded: false,
data: [],
feedbackText:"",
target:[],
refreshing:false,
refreshValue:1
}
}
handleUpdate = async () => {
this.setState({ loaded: false })
await this.getter()
this.forceUpdate();
};
GetData = async () => {
const {date,selected}=this.state
const data = await GetAchieve()
if (data.status == 200) {
this.setState({
data: data.data,
target:data.data !== null ? data.data.filter((achieve) => achieve.date.includes(selected)) : null,
loaded: true,
})
}
}
componentDidMount() {
this._unsubscribe = this.props.navigation.addListener('focus',() => {
console.log('ok')
const UserStatus=this.status()
if(UserStatus){
this.GetData()
}
});
}
_onRefresh=async()=> {
try {
this.setState({refreshing: true});
this.setState(({ refreshValue }) => ({
refreshValue: refreshValue + 1,
}));
this.setState({refreshing: false});
} catch (error) {
throw error
}
}
componentWillUnmount() {
this._unsubscribe();
}
shouldComponentUpdate(nextProps, nextState) {
if(this.state.data != nextState.data){
console.log('data re')
return true;
}
if(this.state.refreshValue != nextState.refreshValue || this.state.selected != nextState.selected || this.state.target != nextState.target ){
console.log('refreshing value')
return true;
}
return false
}
sendFeedBack=async()=>{
const {feedbackText} = this.state
this.validate({
feedbackText: {minlength:3, maxlength:4000},
});
if(!this.isFieldInError('feedbackText')){
const request = await feedback(feedbackText)
if(request.status == 200){
this.setState({
feedbackText:"",
visible:false
})
}
}
}
flag = (date) => {
items = this.state.data !== null ? this.state.data.filter((achieve) => achieve.date.includes(date)) : null
let Professional = false
let Personal = false
if (!!items) {
items.map(item => {
if (item.flag == 1) { Professional = true } else if (item.flag == 2) { Personal = true }
})
if (Professional && Personal) {
return <>
<Text> <Icon name="flag-o" size={10} color="#ff6666" /> </Text>
<Text> <Icon name="star-o" size={10} color="#cc80ff" /> </Text>
</>
} else if (Professional) {
return <Text> <Icon name="flag-o" size={10} color="#ff6666" /> </Text>
} else if (Personal) {
return <Text> <Icon name="star-o" size={10} color="#cc80ff" /> </Text>
}
}
}
week = () => {
const { date, selected,loaded } = this.state
const week = this.state.date.week()
if(loaded){
return (
<>
{week.map((day, index) => {
return (
selected === week[index].plenaDiem ?
<LinearGradient key={index} colors={['#EBDDFD', '#DFDCFF']} start={[0, 1]} end={[1, 0]} style={{ borderRadius: 12 }}>
<TouchableOpacity
key={index}
style={[styles.weekday]}
onPress={() => { this.setState({ selected: week[index].plenaDiem }) }}
disabled={week[index].enable}
>
<Text style={styles.name} >{week[index].dies}</Text>
<Text style={[styles.num, { color: week[index].color }]} >{week[index].diem}</Text>
<View style={styles.flags}>
{this.flag(week[index].plenaDiem)}
</View>
</TouchableOpacity>
</LinearGradient>
:
<TouchableOpacity
key={index}
style={[styles.weekday]}
onPress={() => {
console.log(this.state.target)
this.setState({
selected: week[index].plenaDiem,
target:this.state.data !== null ? this.state.data.filter((achieve) => achieve.date.includes(week[index].plenaDiem)) : null,
})
}}
disabled={week[index].enable}
>
<Text style={styles.name} >{week[index].dies}</Text>
<Text style={[styles.num, { color: week[index].color }]} >
{week[index].diem}
</Text>
<View style={styles.flags}>
{this.flag(week[index].plenaDiem)}
</View>
</TouchableOpacity>
)
})
}
</>
)
}
}
render() {
const { data, date, visible, selected, filter, loaded,feedbackText,refreshing,target } = this.state
// let render = data !== null ? data.filter((achieve) => achieve.date.includes(selected)) : null
// if (filter !== 3 && render !== null) {
// render = render.filter((item) => item.flag == filter)
// }
return (
<>
<View style={styles.header} >
<View style={styles.top}>
<View style={styles.icon}>
<Image source={require('../../assets/header/CalendarIcon.png')} />
<Text style={styles.day}>{date.day()}</Text>
</View>
<View style={styles.items}><Image source={require('../../assets/header/medalLogo.png')} /></View>
<View style={styles.items}><IconButton icon='question' style={styles.question} color={"#000"} size={16} onPress={() => this.setState({ visible: true })} /></View>
</View>
<Modal
visible={visible}
backdropStyle={styles.backdrop}
onBackdropPress={() => this.setState({ visible: false })}>
<Card disabled={true} style={{backgroundColor:"#FFF",width:wp('90%'),borderRadius:10}}>
<Input
name='feedbackText'
value={feedbackText}
style={styles.feedbackText}
multiline={true}
maxLength={4000}
placeholder="tell us about you expermenit"
onChangeText={(text) => { this.setState({
feedbackText: text,
}) }}
/>
<Button
disabled={feedbackText.length<3?true:false}
onPress={() => {this.sendFeedBack()}}>
subimt
</Button>
</Card>
<View style={[styles.close]}>
<AntDesign name={"closecircleo"} color="#000" onPress={() => this.setState({ visible: false })} size={25} />
</View>
</Modal>
<ScrollView
contentContainerStyle={styles.scrollView}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={this._onRefresh.bind(this)}
/>
}
>
<View style={styles.month}>
<Text style={styles.monthName}>{date.monthName()}</Text>
</View>
<View style={styles.week}>
{loaded ? this.week() : <LoadingScreen/>}
</View>
</ScrollView>
</View>
<View style={styles.container} >
<View style={styles.achieve}>
<View>
{/* <SwitchSelector
options={options}
initial={0}
style={styles.switch}
buttonColor={"#fff"}
textColor={"#AB9CB3"}
selectedColor={"#000"}
buttonMargin={3}
imageStyle={styles.switchicon}
backgroundColor={"#F0F1F8"}
onPress={value => this.setState({ filter: value })}
/> */}
</View>
<View style={styles.count}>
<Text style={styles.countText}>you have achieved {target !== null ? target.length : null}</Text>
</View>
</View>
<View style={styles.cards}>
<Cards type={true} data={target} storage={data} handle={this.handleUpdate} />
</View>
</View>
</>
)
}
}
this is calendar component when run it no thing to display but data can be in console log. i can show data there, I need to hit Ctrl+s to refresh expo 'fast refresh' to show data in simulator
I have load Logic in render section but issue is still need fix
any suggestions?
this screen before hit Ctrl+s data is already in state but not rendering "first run"
here after hit Ctrl+s to refresh screen to show data
Related
I am building a flat list with infinite scrolling and a delete items feature.
But every time I delete an item (using a filter) my flat list scrolls to the top.
Delete Function
const deleteItemById = async entry => {
const filteredData = data.filter(item => {
return item.id != entry.id;
});
await setNotificationData(filteredData);
};
Delete Button
<IconButton
onPress={() => {
const notificationToken = globalVariable.token;
const deleteNotificationAPI = async () => {
try {
await axios.delete(`${BASE_URL}${data.id}`,
{
headers: {
Authorization: notificationToken,
},
}
);
} catch (err) {
console.error(err);
}
deleteItemById(data);
};
deleteNotificationAPI();
}}
style={IconButton7a33adf1}
icon={'Foundation/trash'}
size={25}
color={theme.colors.trashCan}
/>
FlatList
This is the flat list that I have been using with renderItem function. It is working fine, deleting the items, it is just scrolling to the top after the filter, I believe this is happening because is rerendering the flatList.
<FlatList
listKey={'s8qdyDKI'}
data={data}
initialNumToRender={30}
windowSize={40}
key={data.length}
ListFooterComponent={<LoadNotifications />}
keyExtractor={item => item?.id || item?.uuid || item}
renderItem={({ item }) => (
<Notifications
data={item}
style={notificationStyles.item}
/>
)}
onEndReached={oneMoreNotificationPage}
onEndReachedThreshold={0.15}
contentContainerStyle={
notificationStyles.FlatList21f2035aContent
}
numColumns={1}
renderItem
function Notifications({ data }) {
return (
<>
<View
style={[notificationStyles.Viewcd452035,
]}
>
<View
style={[notificationStyles.Viewb8b059f4,]}
>
<View
style={[
notificationStyles.Viewb34b4333,]}
>
<Text
style={[
notificationStyles.Text812c3e6d,]}
ellipsizeMode={'tail'}
numberOfLines={1}
>
{data?.title}
</Text>
</View>
<View style={notificationStyles.Viewdebd3207}>
<View style={notificationStyles.View3821c683}>
<Text
style={[
notificationStyles.Text13ddebce,]}
numberOfLines={1}
ellipsizeMode={'tail'}
>
{data?.created_at}
</Text>
</View>
<View style={notificationStyles.Viewc2817b4e}>
<IconButton
onPress={() => {
const notificationToken =
globalVariable.token;
const deleteNotificationAPI = async () =>
{
try {
await axios.delete(
`${BASE_URL}${data?.id}`,
{
headers: {
Authorization:
notificationToken,
},
}
);
} catch (err) {
console.error(err);
}
deleteItemById(data);
console.log('after call');
};
deleteNotificationAPI();
}}
style=
{notificationStyles.IconButton7a33adf1}
icon={'Foundation/trash'}
size={25}
color={theme.colors.trashCan}
/>
</View>
</View>
</View>
</View>
</View>
)}
</>
);
}
I made a Flatlist and and edit button that can open a modal to a text input and track down the key of the specific item. How do I update this item in the Flatlist with the different text input. I tried doing something with the setJournal but I don't know how to return it with the edited entry.
export default function HomeScreen({ navigation }) {
const [journal, setJournal] = useState([
{ date: "12-dec22", entry: "good day", key: "1" },
{ date: "12-dec22", entry: "bad day", key: "2" },
]);
const [editModal, setEditModal] = useState(false);
const handleEditPress = (key) => {
const currentJournal = journal.find((journn) => {
return journn.key === key;
});
setEditModal(true);
console.log(key);
};
const updateEntry = (key, entry) => {
if (journal.key === key) {
setJournal((currentJournal) => {
return [entry, ...currentJournal];
});
} else {}
journal = journal.map((journn) =>
journn.key === key ? { ...journn, ...updateEntry } : journn
);
};
return (
<View>
<Modal visible={editModal}>
<TextInput onChangeText={() => updateEntry()} />
<MaterialIcons name="close" onPress={() => setEditModal(false)} />
</Modal>
<View>
<MaterialIcons onPress={() => setModalOpen(true)}/>
<MaterialIcons onPress={() => deleteAll()} />
</View>
<FlatList
data={journal}
renderItem={({ item }) => (
<View style={styles.flatlistView}>
<TouchableOpacity>
<View>
<MaterialIcons onPress={() => handleEditPress(item.key)}/>
</View>
</TouchableOpacity>
</View>
)}
/>
</View>
);
}
const handleEditPress = (editedField, itemKey)=>{
journal.filter((currentItem.key)=>{(currentItem.key) === itemKey})).text = editedField
setJournal(journal)
}
So I have a tab navigation in my app and I am trying to scan a UPC number from on of the tab screens which is called ScanScreen and send it to the homeScreen where I have a search bar and I want the upc number to show up there once the navigation has been done. So far I am able to scan the upc number and navigate to the homeScreen but for some reason I am not able to send the upc number. I have tried many ways ex. navigation.navigate('HomeScreen',{upc: data}) and the getParam() on the home screen but nothing works.
Obj = scan the upc and then successfully navigate to the homeScreen tab and show the number on the searchBar
export default class HomeScreen extends React.Component {
constructor(props) {
super(props);
this.state = { search: '', isLoading: true };
this.products = [];
}
componentDidMount() {
db.collection("products")
.get()
.then(querySnapshot => {
const data = querySnapshot.docs.map(doc => doc.data());
this.setState({
products: data,
isLoading: false,
dataSource: data
},
function () {
this.products = data;
}
);
}).catch(error => {
console.error(error);
});
}
GetFlag(ingredients, status) {
var Ingredients = Object.values(ingredients);
for (var i = 0; i < Ingredients.length; i++) {
if (Ingredients[i].Status == status)
return true;
}
}
search = text => {
console.log(text);
};
clear = () => {
this.search.clear();
};
SearchFilterFunction(text) {
const newData = this.products.filter(function (item) {
const itemData = item.Name ? item.Name.toUpperCase() :
''.toUpperCase();
const upcData = item.UPC;
const textData = text.toUpperCase();
if (itemData.indexOf(textData) > -1)
return true;
else if (upcData.toString().indexOf(textData) > -1)
return true;
else
return false;
});
this.setState({
dataSource: newData, search: text,
});
}
ListViewItemSeparator = () => {
return (
<View
style={{
height: 0.4,
width: '100%',
backgroundColor: '#141313',
}}
/>
);
};
render() {
const { navigate } = this.props.navigation;
if (this.state.isLoading) {
return (
<View style={{ flex: 1, paddingTop: 21 }}>
<ActivityIndicator />
</View>
);
}
const upc = navigate.getParams('upcCode')
console.log(upc)
return (
<View style={styles.viewStyle}>
<SearchBar round
searchIcon={{ size: 25 }}
onChangeText={text => this.SearchFilterFunction(text)} onClear={text => this.SearchFilterFunction('')}
placeholder="Type Here to Search..." value={this.state.search}
/>
{
this.state.search.trim() != "" ?
<FlatList data={this.state.dataSource}
ItemSeparatorComponent={this.ListViewItemSeparator}
renderItem={({ item }) => (
<View style={styles.container}>
<TouchableHighlight onPress={() => this.props.navigation.navigate('Summary', {
ProductObject: item
})}
>
<View >
{
this.GetFlag(item.ingredients, 'Haram') == true ?
<Image source={images['Haram']} style={styles.imageView} /> :
this.GetFlag(item.ingredients, 'Halal') == true ?
<Image source={images['Halal']} style={styles.imageView} /> :
this.GetFlag(item.ingredients,'Doubtful') == true ?
<Image source={images['Doubtful']} style={styles.imageView} /> :
null
}
<Text style={styles.baseText}>
<Text style={styles.titleText} >
{item.Name}{'\n'}{'\n'}
</Text>
</Text>
</View>
</TouchableHighlight>
</View>
)}
enableEmptySections={true}
style={{ marginTop: 11 }}
keyExtractor={(item, index) => index.toString()}
/> : <FlatList></FlatList>
}
</View>
);
}
}
export default function ScanScreen({navigation}) {
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(false);
useEffect(() => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
const handleBarCodeScanned = ({ type, data }) => {
setScanned(true);
navigation.navigate("Home",{
upcCode: data
})
};
if (hasPermission === null) {
return <Text>Requesting for camera permission</Text>;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<View
style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'flex-end',
}}>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={StyleSheet.absoluteFillObject}
/>
{scanned && <Button title={'Tap to Scan Again'} onPress={() => setScanned(false)} />}
</View>
);
}
Below is my AppNavigator.JS code if it helps seeing the navigation
function MainTabNavigator() {
return (
<Tab.Navigator tabBarOptions={{
activeTintColor: 'red',
inactiveTintColor: 'gray'
}}
screenOptions={({ route }) => ({
tabBarIcon: ({ color, size }) => {
let iconName;
let tabBarVisible = true;
if (route.name == 'Home') {
iconName = 'md-home'
} else if (route.name == 'Scan') {
iconName = 'md-camera'
} else if (route.name == 'Menu') {
iconName = "md-menu"
}
else if (route.name == 'Login') {
iconName = "md-log-in"
}
return <Ionicons name={iconName} color={color} size={size} />
}
})}
>
<Tab.Screen
name='Home'
component={HomeScreen}
options={({route}) => ({
title: "Search for Products",
headerBackTitleVisible: false,
headerStyle: {
backgroundColor: '#1c2845',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontSize:22,
fontFamily: 'DamascusLight'
}
})}
/>
<Tab.Screen
name='Login'
component={LoginScreen}
/>
<Tab.Screen name='Scan' component={ScanScreen} />
<Tab.Screen name='Menu' component={SearchScreen} />
</Tab.Navigator>
)
}
function MainStackNavigator() {
return (
<NavigationContainer>
<Stack.Navigator>
{/* <Stack.Screen name='Login' component={LoginScreen} /> */}
<Stack.Screen name='HomeScreen' component={MainTabNavigator}
options={({ route }) => ({
title: 'Search for Products',
headerBackTitleVisible: false,
headerStyle: {
backgroundColor: '#1c2845',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontSize: 22,
fontFamily: "DamascusLight"
},
}
)} />
<Stack.Screen name='RegistrationScreen' component={RegistrationScreen} />
<Stack.Screen
name="Summary"
component={SummaryScreen}
options={({ route }) => ({
headerTitle: () =>
<View style={styles.header}>
<Text numberOfLines={1} style={styles.title}>{route.params.title}</Text>
<Text numberOfLines={1} style={styles.subtitle}>{route.params.subtitle}</Text>
</View>,
headerBackTitleVisible: false,
headerStyle: {
backgroundColor: '#1c2845',
height: 100
},
headerTintColor: '#fff',
headerTitleStyle: {
fontSize: 12,
fontFamily: "DamascusLight"
},
}
)}
/>
<Stack.Screen
name="ScanSummary"
component={ScanSummary}
// options={({route}) => ({
// headerTitle: () =>
// <View style={styles.header}>
// <Text numberOfLines={1}>{route.params.title}</Text>
// <Text numberOfLines={1}>{route.params.subtitle}</Text>
// </View>,
// headerStyle: {
// backgroundColor: '#1c2845',
// height: 100
// },
// headerTintColor: '#fff',
// headerTitleStyle: {
// fontSize: 12,
// fontFamily: "DamascusLight"
// },
// })}
/>
</Stack.Navigator>
</NavigationContainer>
)
}
export default MainStackNavigator
if you are using react navigation 5
you can access by params by
this.props.route.params
if older
this.props.navigation.state.params
I have created a form to upload the image and text field on the home screen but I am facing a problem that it's not updating the array and validation is failing due to that. I think something wrong with my implementation
AddPost.js
const validationSchema = Yup.object({
title: Yup.string().required().min(5).max(15).label("Title"),
des: Yup.string().required().min(15).max(200).label("Description"),
image: Yup.array().required().label("Image"),
});
class AddPost extends Component {
render() {
return (
<Formik
initialValues={{ title: "", des: "", image: [] }}
onSubmit={(values, actions) => {
actions.resetForm();
this.props.addPost(values);
}}
validationSchema={validationSchema}
>
{(value) => (
<View>
<FormImage />
<Text style={styles.error}>
{value.touched.image && value.errors.image}
</Text>
<TextInput
placeholder="Title"
onChangeText={value.handleChange("title")}
style={styles.input}
value={value.values.title}
onBlur={value.handleBlur("title")}
/>
<Text style={styles.error}>
{value.touched.title && value.errors.title}
</Text>
Here is my form field I think everything is right here
home.js
class Home extends Component {
state = {
modal: false,
post: [
{
key: "1",
title: "A Good Boi",
des: "He's a good boi and every one know it.",
image: require("../assets/dog.jpg"),
},
{
key: "2",
title: "John Cena",
des: "As you can see, You can't see me!",
image: require("../assets/cena.jpg"),
},
],
image: null,
};
addPost = (posts) => {
posts.key = Math.random().toString();
this.setState.post((currentPost) => {
return [posts, ...currentPost];
});
this.state.modal();
};
render() {
return (
<Screen style={styles.screen}>
<Modal visible={this.state.modal} animationType="slide">
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View style={styles.modalContainer}>
<AddPost addPost={() => this.addPost} />
</View>
</TouchableWithoutFeedback>
</Modal>
<FlatList
data={this.state.post}
renderItem={({ item }) => (
<>
<Card
title={item.title}
subTitle={item.des}
image={item.image}
onPress={() => this.props.navigation.navigate("Edit", item)}
/>
</>
I think something wrong with the addPost method because I did it before with function base that time I only added text to the list and its worked but in class base I don't know to do it I just try the same way I did in function base
FormImage.js
class FormImage extends Component {
state = {
image: null,
hasCameraPermission: null,
};
async componentDidMount() {
const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
this.setState({ hasCameraPermission: status === "granted" });
}
_pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4, 3],
});
if (!result.cancelled) {
this.setState({ image: result.uri });
}
};
render() {
const { image } = this.state;
return (
<TouchableWithoutFeedback onPress={this._pickImage}>
<View style={styles.container}>
{!image && (
<MaterialCommunityIcons
color={colors.medium}
name="camera"
size={40}
/>
)}
{image && <Image style={styles.image} source={{ uri: image }} />}
</View>
</TouchableWithoutFeedback>
);
}
}
after submiting
Iam assuming your addPost function logic is wrong,
Try the below code
addPost = (posts) => {
posts.key = Math.random().toString();
this.setState((prevState) => {
return {...prevState, post: [...prevState.post, ...posts] };
});
this.state.modal();
};
Let me know incase you are getting the same error.
You are not updating images to formik so is normal you get the required error.
First in your AddPost Component pass down formikProps to FormImage component.
return (
<Formik
initialValues={{ title: "", des: "", image: [] }}
onSubmit={(values, actions) => {
// actions.resetForm(); --> comment this
this.props.addPost(values);
}}
validationSchema={validationSchema}
>
{(value) => (
<View>
<FormImage formikProps={value}/>
<Text style={styles.error}>
{value.touched.image && value.errors.image}
</Text>
<TextInput
placeholder="Title"
onChangeText={value.handleChange("title")}
style={styles.input}
value={value.values.title}
onBlur={value.handleBlur("title")}
/>
<Text style={styles.error}>
{value.touched.title && value.errors.title}
</Text>
In FormImage use that formikProps and call setFieldValue("image", result.uri) to update formik value for image.
class FormImage extends Component {
state = {
image: null,
hasCameraPermission: null,
};
async componentDidMount() {
const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
this.setState({ hasCameraPermission: status === "granted" });
}
_pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4, 3],
});
if (!result.cancelled) {
this.setState({ image: result.uri });
this.props.formikProps.setFieldValue("image", result.uri);
}
};
render() {
const { image } = this.state;
return (
<TouchableWithoutFeedback onPress={this._pickImage}>
<View style={styles.container}>
{!image && (
<MaterialCommunityIcons
color={colors.medium}
name="camera"
size={40}
/>
)}
{image && <Image style={styles.image} source={{ uri: image }} />}
</View>
</TouchableWithoutFeedback>
);
}
}
In home
addPost = (posts) => {
console.log('add post');
posts.key = Math.random().toString();
this.setState((prevState) => {
return {...prevState, post: [...prevState.post, ...posts], modal:
true };
});
// this.state.modal();
};
Is there any way to check if items are actually being rendered or not? In my code, I run a grapqhl query and then re-render some items accordingly. In my code, if there are users present, the showUsersfunction works correctly.
However, when there are no users the noUsersTextfunction is called as confirmed by console.logs but I don't see anything rendered on the screen. I thought it might be a styling issue but I also tried increasing the font or adding more items to the view - it's clearly not working. What could the issue be?
When the function noUserText is called, both isSubmitted& isNotFoundare printed as true. I am using this in my main jsx {isSubmitted && noUsersText(userData) && isNotFound}so I believe the text should show up.
const [isSubmitted, setIsSubmitted] = useState(false);
const [isNotFound, setIsNotFound] = useState(false);
const [userData, setUserData] = useState<UsersLazyQueryHookResult>('');
const noUsersText = React.useCallback(
(data: UsersLazyQueryHookResult) => {
console.log('isSubmitted', isSubmitted);
console.log('Not Found', isNotFound);
if (data) {
if (data.users.nodes.length == 0) {
return (
<View>
<Text style={styles.noUsers}>No Users Found</Text>
</View>
);}
}
},
[userData],
);
const showUsers = React.useCallback(
(data: UsersLazyQueryHookResult) => {
if (data) {
return (
<View style={styles.friends}>
{data.users.nodes.map(
(item: { firstName: string; lastName: string; id: number }) => {
const userName = item.firstName
.concat(item.lastName);
return (
<View
style={styles.item} key={item.id}>
<View style={styles.addButtonContainer}>
<Button
rounded
style={styles.addButton}
onPress={() => {
addFriend(Number(item.id));
setIsSubmitted(false);
setUserData(null);
}}>
</Button>
</View>
</View>
);
},
)}
</View>
);
}
},
[createUserRelationMutation, userData],
);
const addFriend = React.useCallback(
(id: Number) => {
createUserRelationMutation({
variables: {
..,
},
});
},
[createUserRelationMutation],
);
const getFriendId = React.useCallback(
(data: UsersLazyQueryHookResult) => {
if (data) {
if (data.users.nodes.length == 0) {
setUserData(data);
setIsNotFound(true);
//Alert.alert('User Not Found');
} else {
setUserData(data);
}
}
},
[addFriend],
);
const [loadUsers] = useUsersLazyQuery({
onCompleted: getFriendId,
onError: _onLoadUserError,
});
const handleSubmitForm = React.useCallback(
(values: FormValues, helpers: FormikHelpers<FormValues>) => {
setIsSubmitted(true);
console.log('Submitted');
loadUsers({
variables: {
where: { email: values.email },
},
});
values.email = '';
},
[loadUsers],
);
return (
<Modal
visible={showAddFriendEmailPage}
animationType="slide"
transparent={true}>
<SafeAreaView>
<View style={styles.container}>
<View style={styles.searchTopContainer}>
<View style={styles.searchTopTextContainer}>
<Text
style={styles.searchCancelDoneText}
onPress={() => {
toggleShowPage();
setIsSubmitted(false);
setUserData(null);
setIsNotFound(false);
}}>
Cancel
</Text>
<Text style={styles.searchTopMiddleText}>
Add Friend by Email
</Text>
<Text style={styles.searchCancelDoneText}>Done</Text>
</View>
<View>
<Formik
initialValues={initialValues}
onSubmit={handleSubmitForm}
validationSchema={validationSchema}>
{({ handleChange, handleBlur, handleSubmit, values }) => (
<View style={styles.searchFieldContainer}>
<View style={styles.form}>
<FieldInput
handleChange={handleChange}
handleBlur={handleBlur}
value={values.email}
placeholderText='a#example.com'
/>
</View>
<View style={styles.buttonContainer}>
<Button
rounded
style={styles.button}
onPress={handleSubmit}>
<Text style={styles.text}>Search </Text>
</Button>
</View>
</View>
)}
</Formik>
</View>
{isSubmitted && showUsers(userData)}
{isSubmitted && noUsersText(userData) && isNotFound}
</View>
</View>
</SafeAreaView>
</Modal>
);
};
React doesn't render boolean, undefined or null values. Also note that when you write conditional rendering like
{isSubmitted && noUsersText(userData) && isNotFound}
The result is returned on the first falsy value. Otherwise the last truthy value is returned
So in your case the above code return true instead of the View component
Change the above to
{isSubmitted && isNotFound && noUsersText(userData)}
and it should work