#javascript #android #react-native #graphql #apollo-client
#javascript #Android #react-native #graphql #apollo-клиент
Вопрос:
Я создаю приложение Android React Native с клиентом Apollo, которое подключается к серверной части GraphQL.
Я настроил экран входа в систему, на котором пользователи могут вводить свое имя пользователя и пароль и выполнять запрос для входа при нажатии / нажатии кнопки.
При первой загрузке приложения (или сразу после обновления приложения) все нормально. Ничего необычного, когда я ввожу учетные данные с первой попытки и успешно вхожу в систему. Но после одной неудачной попытки входа в систему (либо из-за ошибки сети, либо из-за неверных учетных данных), каждый раз, когда я набираю или удаляю один символ из любого из текстовых вводов, запрос входа из useLazyQuery выполняется без нажатия кнопки входа. Проблема исчезает только тогда, когда я закрываю и перезапускаю приложение.
Является ли onChangeText причиной этого? Я неправильно использую useLazyQuery? Я что-то здесь упускаю?
Вот код:
import React, { useState, useContext, useRef } from 'react';
import { View, Text, TextInput, ToastAndroid } from 'react-native';
import { TouchableOpacity } from 'react-native-gesture-handler';
import { gql, useLazyQuery } from '@apollo/client';
import AsyncStorage from '@react-native-community/async-storage';
import AuthContext from '../context/AuthContext';
import Loading from '../components/Loading';
const LOGIN = gql`
query Login (
$username: String!
$password: String!
) {
login (
username: $username
password: $password
) {
token
}
}
`;
const Login = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const { setAuthLoading } = useContext(AuthContext);
const nextInputRef = useRef();
const setToken = async (token) => {
await AsyncStorage.setItem('token', token);
setAuthLoading(true);
};
const [queryLogin, { loading, error, data }] = useLazyQuery(LOGIN);
if (loading) return <Loading />;
if (error) ToastAndroid.show(error.message, ToastAndroid.SHORT);
if (data amp;amp; data.login amp;amp; data.login.token) {
setToken(data.login.token);
}
const sendLogin = () => {
queryLogin({ variables: { username, password } })
};
return (
<View>
<TextInput
value={username}
onChangeText={(text) => setUsername(text)}
placeholder="USERNAME"
returnKeyType="next"
onSubmitEditing={() => nextInputRef.current.focus()}
></TextInput>
<TextInput
secureTextEntry={true}
value={password}
onChangeText={(text) => setPassword(text)}
placeholder="PASSWORD"
returnKeyType="done"
ref={nextInputRef}
onSubmitEditing={() => sendLogin()}
></TextInput>
<TouchableOpacity onPress={() => sendLogin()}>
<Text>LOGIN</Text>
</TouchableOpacity>
</View>
);
};
Вот мои связанные версии стека:
"@apollo/client": "^3.2.1",
"@react-native-community/async-storage": "^1.12.0",
"graphql": "^15.3.0",
"react": "16.13.1",
"react-native": "0.63.2",
"react-native-gesture-handler": "^1.8.0",
Комментарии:
1. не объявляйте переменные в hook, передавайте их в onPress
2. @xadm Я попробовал ваш совет, и проблема все еще сохраняется, но что-то изменилось. Он больше не переходит к компоненту <Loading /> каждый раз, когда я что-то печатаю. Так что спасибо за это.
3. почему бы не использовать
useMutation
? почемуonSubmitEditing={() => sendLogin()}
?4. @xadm ну, серверный API входа в систему — это запрос. Я не создавал серверный API. В любом случае я изменил метод на
useApolloClient
, и он сработал. В любом случае спасибо за помощь 🙂