Когда я пытаюсь прочитать содержимое кэша данного ключа, я получаю неопределенное значение даже после того, как вызываю useMutation с точно таким же ключом.
Мутация, используемая для установки кеша (мутация возвращает правильные данные, как и ожидалось):
const axiosInstance = axios.create(habiticaAPIconf);
function parseResponse(response:LoginDataContract):AuthData{
return {
id: response.data.id,
apiToken: response.data.apiToken,
username: response.data.username
}
}
const getAuthenticationData = async (userCredentials:UserCredentials):Promise<AuthData> => {
const response = await axiosInstance.post<LoginDataContract>("/user/auth/local/login", {...userCredentials});
return parseResponse(response.data);
}
export function useCredentialData() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (loginData:UserCredentials):Promise<AuthData> => getAuthenticationData(loginData),
mutationKey: ['authData']
});
};
Компонент, используемый для запуска мутации:
export function LoginForm() {
const { mutate, isSuccess, data } = useCredentialData();
function handleLogin(e: MouseEvent<HTMLButtonElement, globalThis.MouseEvent>) {
e.preventDefault();
mutate({
username: (document.getElementById("email") as HTMLInputElement).value,
password: (document.getElementById("password") as HTMLInputElement).value
});
console.info(data);
}
return (
<form>
<label htmlFor = "email">
<input type = "email" name = "email" id = "email"></input>
</label>
<label htmlFor = "password">
<input type = "password" name = "password" id = "password"></input>
</label>
<button type = "submit" onClick = { (e)=> {handleLogin(e)}}>Login</button>
<span>{isSuccess ? `${data.username}` : ""}</span>
</form>
)
}
При нажатии кнопки в компоненте React всегда возвращается неопределенное значение даже после вызова вышеупомянутой мутации и возвращает правильные данные.
import { useQueryClient } from "@tanstack/react-query";
export function SidebarTasksList() {
const queryClient = useQueryClient();
return (
<section>
<button onClick = {
()=>console.info(queryClient.getQueryData(['authData']))
}>CLICK</button>
</section>
);
Как получить данные, хранящиеся в кеше ['AuthData']
? Также нет функции, которую я мог бы передать useQuery
как queryFn
, поэтому я использую getQueryData
.
Вообще говоря, mutations
и queries
не имеют никакой корреляции. Установка одного и того же ключа на них обоих не приведет к тому, что они узнают друг о друге. mutationKey
также не является обязательным. Ни один из примеров на самом деле не устанавливает ключ, если я правильно помню, потому что он в основном используется для обмена конфигурацией между мутациями.
Чтобы «связать» результат ваших мутаций с вашими запросами, вам нужно либо:
return useMutation({
mutationFn: (loginData:UserCredentials):Promise<AuthData> => getAuthenticationData(loginData),
onSuccess: () => queryClient.invalidateQueries(['authData'])
});
return useMutation({
mutationFn: (loginData:UserCredentials):Promise<AuthData> => getAuthenticationData(loginData),
onSuccess: (data) => queryClient.setQueryData(['authData'], data)
});
Инвалидацию очень рекомендуется делать, потому что это наименьший объем кода, и он всегда будет работать, даже если вы добавите код позже. Попытка оптимизировать минимальное количество сетевых запросов кажется немного неоптимальной.
Ладно, думаю, мы немного не поняли друг друга. В API я работаю с единственным способом получения учетных данных — с помощью почтового вызова, как я делаю в функции getAuthenticationData
. В моем коде с ключом authData
нет определения useQuery. В данном случае, если я правильно понимаю: инвалидация приведет либо к очистке authData
кеша, либо ни к чему (потому что queryFn
не назначено authData
). Итак, теперь я думаю, что вместо useMutation мне следует использовать useQuery и передать туда почтовый вызов как querFn. Как вы думаете, это лучший подход?
Первое предложение очень похоже на anitpattern, даже если API, с которым я работаю, не будет возвращать данные, я бы использовал setQueryData, второй подход работал отлично.