Bounty: 50
I have a screen where the user inputs a phone number. I run a graphql query loadUsers
according to the input and then display the search results via the showUsers
function. It works fine on the first time. I get the results. However, after that, when the results are conditionally rendered, the search button becomes disabled. So if I want to type in a different phone number and hit the search button again, I can’t do this. Unless I exit the screen and then come back. How can I fix this?
Here’s what my code looks like:
export const AddContactTry: React.FunctionComponent = () => {
const initialValues: FormValues = {
phoneNumber: '',
};
const [isSubmitted, setIsSubmitted] = useState(false);
const [userData, setUserData] = useState<UsersLazyQueryHookResult>('');
const navigation = useNavigation();
const validationSchema = phoneNumberValidationSchema;
const [
createUserRelationMutation,
{
data: addingContactData,
loading: addingContactLoading,
error: addingContactError,
called: isMutationCalled,
},
] = useCreateUserRelationMutation({
onCompleted: () => {
Alert.alert('Contact Added');
},
});
const showUsers = React.useCallback(
(data: UsersLazyQueryHookResult) => {
if (data) {
return (
<View style={styles.users}>
{data.users.nodes.map(
(item: { firstName: string; lastName: string; id: number }) => {
const userName = item.firstName
.concat(' ')
.concat(item.lastName);
return (
<View style={styles.item} key={item.id}>
<Thumbnail
style={styles.thumbnail}
source={{
uri:
'https://cdn4.iconfinder.com/data/icons/avatars-xmas-giveaway/128/afro_woman_female_person-512.png',
}}></Thumbnail>
<Text style={styles.userName}>{userName}</Text>
<View style={styles.addButtonContainer}>
<Button
rounded
style={styles.addButton}
onPress={() => {
addContact(Number(item.id));
setIsSubmitted(false);
setUserData(null);
}}>
<Icon
name="plus"
size={moderateScale(20)}
color="black"
/>
</Button>
</View>
</View>
);
},
)}
</View>
);
}
},
[createUserRelationMutation, userData],
);
const addContact = React.useCallback(
(id: Number) => {
console.log('Whats the Id', id);
createUserRelationMutation({
variables: {
input: { relatedUserId: id, type: RelationType.Contact, userId: 30 },
},
});
},
[createUserRelationMutation],
);
const getContactId = React.useCallback(
(data: UsersLazyQueryHookResult) => {
if (data) {
if (data.users.nodes.length == 0) {
Alert.alert('No User Found');
} else {
setUserData(data);
}
}
},
[addContact],
);
const [loadUsers] = useUsersLazyQuery({
onCompleted: getContactId,
onError: _onLoadUserError,
});
const handleSubmitForm = React.useCallback(
(values: FormValues, helpers: FormikHelpers<FormValues>) => {
setIsSubmitted(true);
const plusSign = '+';
const newPhoneNumber = plusSign.concat(values.phoneNumber);
loadUsers({
variables: {
where: { phoneNumber: newPhoneNumber },
},
});
values.phoneNumber = '';
},
[loadUsers],
);
return (
<SafeAreaView>
<View style={styles.container}>
<View style={styles.searchTopContainer}>
<View style={styles.searchTopTextContainer}>
</View>
<View>
<Formik
initialValues={initialValues}
onSubmit={handleSubmitForm}
validationSchema={validationSchema}
>
{({ handleChange, handleBlur, handleSubmit, values, isValid, dirty }) => (
<View style={styles.searchFieldContainer}>
<View style={styles.form}>
<FieldInput style={styles.fieldInput}
handleChange={handleChange}
handleBlur={handleBlur}
value={values.phoneNumber}
fieldType="phoneNumber"
icon="phone"
placeholderText="49152901820"
/>
<ErrorMessage
name="phoneNumber"
render={(msg) => (
<Text style={styles.errorText}>{msg}</Text>
)}
/>
</View>
<View style={styles.buttonContainer}>
<Text>Abbrechen</Text>
</Button>
<Button
block
success
disabled={!isValid || !dirty}
onPress={handleSubmit}
style={styles.button}>
<Text>Speichern</Text>
</Button>
</View>
</View>
)}
</Formik>
</View>
{isSubmitted && showUsers(userData)}
</View>
</View>
</SafeAreaView>
);
};
Edit:
As suggested in comments, I tried using useFormik instead of but couldn’t make that work.
export const AddContactTry: React.FunctionComponent = () => {
const { values, handleChange, handleSubmit, dirty, handleBlur, isValid}= useFormik({
initialValues: {
phoneNumber: '',
},
onSubmit: values => {
handleSubmitForm(values);
},
});
const [isSubmitted, setIsSubmitted] = useState(false);
const [userData, setUserData] = useState<UsersLazyQueryHookResult>('');
const navigation = useNavigation();
const validationSchema = phoneNumberValidationSchema;
const [
createUserRelationMutation,
{
data: addingContactData,
loading: addingContactLoading,
error: addingContactError,
called: isMutationCalled,
},
] = useCreateUserRelationMutation({
onCompleted: () => {
Alert.alert('Contact Added');
},
});
const showUsers = React.useCallback(
(data: UsersLazyQueryHookResult) => {
if (data) {
return (
<View style={styles.users}>
{data.users.nodes.map(
(item: { firstName: string; lastName: string; id: number }) => {
const userName = item.firstName
.concat(' ')
.concat(item.lastName);
return (
<View style={styles.item} key={item.id}>
<Thumbnail
style={styles.thumbnail}
source={{
uri:
'https://cdn4.iconfinder.com/data/icons/avatars-xmas-giveaway/128/afro_woman_female_person-512.png',
}}></Thumbnail>
<Text style={styles.userName}>{userName}</Text>
<View style={styles.addButtonContainer}>
<Button
rounded
style={styles.addButton}
onPress={() => {
addContact(Number(item.id));
setIsSubmitted(false);
setUserData(null);
}}>
<Icon
name="plus"
size={moderateScale(20)}
color="black"
/>
</Button>
</View>
</View>
);
},
)}
</View>
);
}
},
[createUserRelationMutation, userData],
);
const addContact = React.useCallback(
(id: Number) => {
console.log('Whats the Id', id);
createUserRelationMutation({
variables: {
input: { relatedUserId: id, type: RelationType.Contact, userId: 30 },
},
});
},
[createUserRelationMutation],
);
const getContactId = React.useCallback(
(data: UsersLazyQueryHookResult) => {
if (data) {
if (data.users.nodes.length == 0) {
Alert.alert('No User Found');
} else {
setUserData(data);
}
}
},
[addContact],
);
const [loadUsers] = useUsersLazyQuery({
onCompleted: getContactId,
onError: _onLoadUserError,
});
const handleSubmitForm = React.useCallback(
(values: FormValues) => {
setIsSubmitted(true);
const plusSign = '+';
const newPhoneNumber = plusSign.concat(values.phoneNumber);
console.log('Submitted');
loadUsers({
variables: {
where: { phoneNumber: newPhoneNumber },
},
});
values.phoneNumber = '';
},
[loadUsers],
);
return (
<SafeAreaView>
<View style={styles.container}>
<View style={styles.searchTopContainer}>
<View style={styles.searchTopTextContainer}>
</View>
<View>
<View style={styles.searchFieldContainer}>
<View style={styles.form}>
{/* <FieldInput style={styles.fieldInput}
handleChange={handleChange}
handleBlur={Formik.handleBlur}
value={Formik.values.phoneNumber}
fieldType="phoneNumber"
icon="phone"
placeholderText="49152901820"
/> */}
<Input style={styles.fieldInput}
onChangeText={handleChange('phoneNumber') as (text: string) => void}
onBlur={handleBlur('phoneNumber') as (event: any) => void}
value={values.phoneNumber}
//name="phoneNumber"
//fieldType="phoneNumber"
//icon="phone"
placeholder="49152901820"
/>
<ErrorMessage
name="phoneNumber"
render={(msg) => (
<Text style={styles.errorText}>{msg}</Text>
)}
/>
</View>
<View style={styles.buttonContainer}>
<Button
block
success
disabled={!isValid || !dirty}
onPress={handleSubmit}
style={styles.button}>
<Text>Speichern</Text>
</Button>
</View>
</View>
</View>
{isSubmitted && showUsers(userData)}
</View>
</View>
</SafeAreaView>
);
};
Get this bounty!!!