У меня есть экран, на котором пользователь вводит номер телефона. Я запускаю запрос graphql loadUsers
в соответствии с вводом, а затем отображаю результаты поиска с помощью функции showUsers
. С первого раза работает нормально. Я получаю результаты. Однако после этого, когда результаты отображаются условно, кнопка поиска становится недоступной. Поэтому, если я хочу ввести другой номер телефона и снова нажать кнопку поиска, я не смогу этого сделать. Если только я не выйду из экрана и не вернусь. Как я могу это исправить?
Вот как выглядит мой код:
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:
Как было предложено в комментариях, я попытался использовать useFormik вместо и переместил showUsers в отдельный компонент, но он тоже не сработало. Кнопка по-прежнему отключается после первого запроса.
export const AddContactTry: React.FunctionComponent = () => {
const validationSchema = phoneNumberValidationSchema;
const { values, handleChange, handleSubmit, dirty, handleBlur, isValid, resetForm, isSubmitting, setSubmitting, touched}= useFormik({
initialValues: {
phoneNumber: '',
},
//isInitialValid:false,
validationSchema,
onSubmit: (values: FormValues) => {
handleSubmitForm(values);
},
});
console.log('isDirty', dirty);
console.log('isValid', isValid);
console.log('phone numm', values.phoneNumber);
console.log('submitting status', isSubmitting);
const [isSubmitted, setIsSubmitted] = useState(false);
const [userData, setUserData] = useState<UsersLazyQueryHookResult>('');
const navigation = useNavigation();
const _onLoadUserError = React.useCallback((error: ApolloError) => {
Alert.alert('Oops, try again later');
}, []);
// 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) => {
//resetForm();
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 },
},
});
resetForm();
},
[loadUsers],
);
// if (!addingContactLoading && isMutationCalled) {
// if (addingContactError) {
// Alert.alert('Unable to Add Contact');
// }
// }
return (
<SafeAreaView>
<View style={styles.container}>
<View style={styles.searchTopContainer}>
<View>
<View style={styles.searchFieldContainer}>
<View style={styles.form}>
<Item underline style={styles.newFieldInput} >
<Icon name="mobile" color="black" size={26}></Icon>
<Input
onChangeText={handleChange('phoneNumber') as (text: string) => void}
onBlur={handleBlur('phoneNumber') as (event: any) => void}
value={values.phoneNumber}
placeholder="49152901820"
/>
</Item>
</View>
<View style={styles.buttonContainer}>
<Button
block
danger
bordered
style={styles.button}
// onPress={() => navigation.goBack()}
//disabled={!isValid || !dirty}
//disabled={isSubmitting}
onPress={resetForm}
>
<Text>Abbrechen</Text>
</Button>
<Button
block
success
disabled={!isValid || !dirty}
onPress={handleSubmit}
style={styles.button}>
<Text>Speichern</Text>
</Button>
</View>
</View>
</View>
{/* {isSubmitted && showUsers(userData)} */}
<User data={userData}></User>
</View>
</View>
</SafeAreaView>
);
};
type UserProps = {
data: UsersLazyQueryHookResult;
//isSubmitted: boolean;
};
export const User: React.FunctionComponent<UserProps> = ({
data,
//isSubmitted,
}) => {
console.log('user called');
const [
createUserRelationMutation,
{
data: addingContactData,
loading: addingContactLoading,
error: addingContactError,
called: isMutationCalled,
},
] = useCreateUserRelationMutation({
onCompleted: () => {
Alert.alert('Contact Added');
},
});
const addContact = React.useCallback(
(id: Number) => {
console.log('Whats the Id', id);
createUserRelationMutation({
variables: {
input: { relatedUserId: id, type: RelationType.Contact, userId: 30 },
},
});
},
[createUserRelationMutation],
);
if (!addingContactLoading && isMutationCalled) {
if (addingContactError) {
Alert.alert('Unable to Add Contact');
}
}
if (!data) return null;
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>
);
};
Кнопка должна быть отключена (серая), когда она пуста (не грязная) и недействительна (``! IsValid). Если он грязный и действительный, кнопка становится зеленой. В настоящее время после выполнения первого запроса и получения результатов, если я ввожу что-то действительное в поле ввода, кнопка становится зеленой с серой. Однако я не могу "щелкнуть" по нему.