Я хочу вызывать useQuery всякий раз, когда мне это нужно,
но использовать Query внутри функции нельзя.
Мой пробный код:
export const TestComponent = () => {
...
const { data, loading, error } = useQuery(gql(GET_USER_LIST), {
variables: {
data: {
page: changePage,
pageSize: 10,
},
},
})
...
...
const onSaveInformation = async () => {
try {
await updateInformation({...})
// I want to call useQuery once again.
} catch (e) {
return e
}
}
...
Как вызвать useQuery несколько раз?
Могу ли я вызвать, когда захочу?
Я искал несколько сайтов, но не мог найти решения.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


useQuery — это декларативный React Hook. Она не предназначена для вызова в смысле классической функции для получения данных. Во-первых, убедитесь, что вы понимаете React Hooks или просто пока не используете их (90% вопросов на Stackoverflow возникают из-за того, что люди пытаются узнать слишком много вещей одновременно). Документация Apollo очень хороша для официального пакета react-apollo, который использует свойства рендеринга. Это работает так же хорошо, и как только вы поняли хуки Apollo Client а также, вы можете провести небольшой рефакторинг. Итак, ответы на ваши вопросы:
How do I call useQuery multiple times?
Вы не называете это несколько раз. Компонент будет автоматически перерисовываться, когда результат запроса будет доступен или обновлен.
Can I call it whenever I want?
Нет, хуки можно вызывать только на верхнем уровне. Вместо этого данные доступны в вашей функции из верхней области видимости (закрытие).
Ваш updateInformation, вероятно, должен быть мутацией, которая обновляет кеш приложения, что снова вызывает повторную визуализацию компонента React, потому что он «подписан» на запрос. В большинстве случаев обновление происходит полностью автоматически, потому что Apollo идентифицирует объекты по комбинации __typename и id. Вот некоторый псевдокод, который иллюстрирует, как мутации работают вместе с мутациями:
const GET_USER_LIST = gql`
query GetUserList {
users {
id
name
}
}
`;
const UPDATE_USER = gql`
mutation UpdateUser($id: ID!, $name: String!) {
updateUser(id: $id, update: { name: $name }) {
success
user {
id
name
}
}
}
`;
const UserListComponen = (props) => {
const { data, loading, error } = useQuery(GET_USER_LIST);
const [updateUser] = useMutation(UPDATE_USER);
const onSaveInformation = (id, name) => updateUser({ variables: { id, name });
return (
// ... use data.users and onSaveInformation in your JSX
);
}
Теперь, если имя пользователя изменится в результате мутации, Apollo автоматически обновит кеш и вызовет повторную визуализацию компонента. Затем компонент автоматически отобразит новые данные. Добро пожаловать в мощь GraphQL!
Спасибо за описание. Я просто не понимаю, как эта функция может быть отображена. Единственный способ рендеринга функциональных компонентов — это их собственное состояние или свойства. Но когда я делаю console.info(реквизиты), он пуст, но в ответ он все равно перерисовывается, когда загрузка ложна.
Из документов Аполлона
When React mounts and renders a component that calls the useQuery hook, Apollo Client automatically executes the specified query. But what if you want to execute a query in response to a different event, such as a user clicking a button?
The useLazyQuery hook is perfect for executing queries in response to events other than component rendering
Я предлагаю использоватьLazyQuery. Проще говоря, использовать запрос будет запускаться при рендеринге вашего компонента, вы можете использовать опцию skip, чтобы пропустить начальный запуск. И есть несколько способов обновить / получить больше данных, когда захотите. Или вы можете придерживаться useLazyQuery
Например, если вы хотите получать данные только тогда, когда пользователь нажимает кнопку или прокручивает страницу вниз, вы можете использовать useLazyQuery хук.
Этот ответ должен был быть принятым ответом в соответствии с заголовком сообщения. Позвольте мне проголосовать за это.
неправда, что его (useQuery) нельзя остановить.... есть опция "пропустить"
В ответах упоминается, как следует использовать useQuery, а также предложения по использованию useLazyQuery. Я думаю, что ключевым моментом является понимание вариантов использования useQuery и useLazyQuery, которые вы можете прочитать в документации. Ниже я попытаюсь объяснить это со своей точки зрения.
использовать запрос является «декларативным», как и остальная часть React, особенно рендеринг компонентов. Это означает, что вы должны ожидать, что useQuery будет вызываться при каждом рендеринге при изменении состояния или свойств. Итак, по-английски это звучит так: «Эй, React, когда что-то изменится, это какие, я хочу, чтобы вы запросили».
для использоватьLazyQuery эта строка в документации является ключевой: «Хук useLazyQuery идеально подходит для выполнения запросов в ответ на события, отличные от рендеринга компонента». Говоря более общим языком программирования, это «императивно». Это дает вам возможность вызывать запрос так, как вы хотите, будь то в ответ на изменения состояния/свойства (например, с помощью useEffect) или обработчики событий, такие как нажатия кнопок. На английском это звучит так: «Привет, React, это как, я хочу запросить данные».
Вы можете использовать fetchMore(), возвращенную из useQuery, которая в первую очередь предназначена для разбиения на страницы.
const { loading, client, fetchMore } = useQuery(GET_USER_LIST);
const submit = async () => {
// Perform save operation
const userResp = await fetchMore({
variables: {
// Pass any args here
},
updateQuery(){
}
});
console.info(userResp.data)
};
Подробнее здесь: fetchПодробнее
Вы также можете использовать useLazyQuery, однако это даст вам функцию, которая возвращает пустота, а данные возвращаются за пределами вашей функцией.
const [getUser, { loading, client, data }] = useLazyQuery(GET_USER_LIST);
const submit = async () => {
const userResp = await getUser({
variables: {
// Pass your args here
},
updateQuery() {},
});
console.info({ userResp }); // undefined
};
Подробнее здесь: использоватьLazyQuery
Пожалуйста, используйте
const { loading, data, refetch } = useQuery(Query_Data)
и вызовите его, когда вам это нужно, т.е.
refetch()
refetch() не обновляет и не перезагружает, обновляет, когда параметр совпадает с загрузкой перед вызовом из наличных, а не с сервера
Вы можете создать повторно используемую функцию выборки, как показано ниже:
// Create query
const query = `
query GetUserList ($data: UserDataType){
getUserList(data: $data){
uid,
first_name
}
}
`;
// Component
export const TestComponent (props) {
const onSaveInformation = async () => {
// I want to call useQuery once again.
const getUsers = await fetchUserList();
}
// This is the reusable fetch function.
const fetchUserList = async () => {
// Update the URL to your Graphql Endpoint.
return await fetch('http://localhost:8080/api/graphql?', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
body: JSON.stringify({
query,
variables: {
data: {
page: changePage,
pageSize: 10,
},
},
})
}).then(
response => { return response.json(); }
).catch(
error => console.info(error) // Handle the error response object
);
}
return (
<h1>Test Component</h1>
);
}Вот альтернатива, которая сработала для меня:
const { refetch } = useQuery(GET_USER_LIST, {
variables: {
data: {
page: changePage,
pageSize: 10,
},
},
}
);
const onSaveInformation = async () => {
try {
await updateInformation({...});
const res = await refetch({ variables: { ... }});
console.info(res);
} catch (e) {
return e;
}
}
А вот аналогичный отвечать по похожему вопросу.
Если кто-то еще не получил полной картины, вот довольно хороший пример. Ultimatecourses.com/blog/…