反应中的奇怪错误 - 使用 apollo/client - graphql
Weird error in react - using apollo/client - graphql
我正在开发一个 MERNG 应用程序,到目前为止一切正常,但我在 useMutations 的前面遇到了一些错误,让我向您解释一下。
因此,在 login/register 部分,如果您将字段留空或在登录名中留空,如果您的用户未在数据库中找到,它将给出错误,我在函数中收到这些错误onError(err),但是,问题是,它总是给我错误,它说,无法读取未定义的 属性 'extensions',即使我没有错误,它也会给出错误,让我显示代码
import React, { useState } from "react";
import { useMutation, gql } from "@apollo/client";
import { useHistory } from "react-router-dom";
import { useDispatch } from "react-redux";
import {
FormAuth,
TitleAuth,
TitleAuthImage,
ContainInput,
InputAuth,
ContainSingleInput,
ContainButtons,
Button,
ButtonSpan
} from "../../website/Auth/AuthStyled";
import instagram from "../../img/instagram.svg";
import Loading from "../Loading/Loading";
const Login = ({ setLogin }) => {
const history = useHistory();
const dispatch = useDispatch();
const [userData, setUserData] = useState({
email: "",
password: ""
});
const [errors, setErrors] = useState({});
const [addUser, { loading }] = useMutation(LOGIN_MUTATION, {
update(
_,
{
data: { login: data }
}
) {
dispatch({ type: "LOGIN", payload: data });
history.push(`/profile/${data.id}`);
},
onError(err) {
setErrors(err.graphQLErrors[0].extensions.exception.errors);
},
variables: userData
});
const handleSubmit = e => {
e.preventDefault();
addUser();
setUserData({ email: "", password: "" });
};
// Framer motion animations
const PopUp = {
hidden: { x: 1000 },
visible: {
x: 0,
transition: { duration: 0.7 }
}
};
return (
<>
{!loading ? (
<FormAuth
onSubmit={handleSubmit}
variants={PopUp}
initial="hidden"
animate="visible"
>
<TitleAuth>
<TitleAuthImage src={instagram} />
</TitleAuth>
<ContainInput>
<ContainSingleInput top="2rem">
<InputAuth
name="email"
type="email"
placeholder={errors.email ? errors.email : "Email"}
maxLength="50"
value={userData.email}
onChange={e =>
setUserData({ ...userData, email: e.target.value })
}
/>
</ContainSingleInput>
<ContainSingleInput top="7rem">
<InputAuth
name="password"
type="password"
placeholder={errors.password ? errors.password : "Password"}
maxLength="50"
value={userData.password}
onChange={e =>
setUserData({ ...userData, password: e.target.value })
}
/>
</ContainSingleInput>
</ContainInput>
<ContainButtons>
<Button
type="submit"
Login
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.85 }}
>
Login
</Button>
<ButtonSpan
Register
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.85 }}
onClick={() => setLogin(false)}
>
Register
</ButtonSpan>
</ContainButtons>
</FormAuth>
) : (
<Loading />
)}
</>
);
};
const LOGIN_MUTATION = gql`
mutation login($email: String!, $password: String!) {
login(email: $email, password: $password) {
id
email
password
token
}
}
`;
export default Login;
这是登录的样子,那里的凭据是正确的
点击登录后浏览器报错
这里奇怪的是,它以前正常工作,但知道它坏了,我不知道为什么或如何,如果我有错误,它们会出现在输入的占位符中,但要知道,它总是休息
根据 apollo 文档 onError for useMutation passes an ApolloError 其中包含几个元素。
对于当前的实现,您假设 onError
中有这样一个 graphQLErrors
元素,并且它确实填充了至少 1 个元素。情况可能并非如此。出于这个原因,当您尝试访问 err.graphQLErrors[0]
时,您会得到 undefined
,这会导致您的特定错误。
docs 建议在采取行动之前测试特定错误的证据:
onError(({graphQLErrors, networkError}) => {
if (graphQLErrors)
graphQLErrors.forEach(({message, locations, path}) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
),
);
if (networkError) {
console.log(`[Network error]: ${networkError}`);
}
});
或者,您可以使用 tracking loading and error state
的内置机制
const [addUser,
{loading: mutationLoading, error: mutationError}] = useMutation(LOGIN_MUTATION, {
update(
_,
{
data: {login: data}
}
) {
dispatch({type: "LOGIN", payload: data});
history.push(`/profile/${data.id}`);
},
variables: userData
});
我正在开发一个 MERNG 应用程序,到目前为止一切正常,但我在 useMutations 的前面遇到了一些错误,让我向您解释一下。
因此,在 login/register 部分,如果您将字段留空或在登录名中留空,如果您的用户未在数据库中找到,它将给出错误,我在函数中收到这些错误onError(err),但是,问题是,它总是给我错误,它说,无法读取未定义的 属性 'extensions',即使我没有错误,它也会给出错误,让我显示代码
import React, { useState } from "react";
import { useMutation, gql } from "@apollo/client";
import { useHistory } from "react-router-dom";
import { useDispatch } from "react-redux";
import {
FormAuth,
TitleAuth,
TitleAuthImage,
ContainInput,
InputAuth,
ContainSingleInput,
ContainButtons,
Button,
ButtonSpan
} from "../../website/Auth/AuthStyled";
import instagram from "../../img/instagram.svg";
import Loading from "../Loading/Loading";
const Login = ({ setLogin }) => {
const history = useHistory();
const dispatch = useDispatch();
const [userData, setUserData] = useState({
email: "",
password: ""
});
const [errors, setErrors] = useState({});
const [addUser, { loading }] = useMutation(LOGIN_MUTATION, {
update(
_,
{
data: { login: data }
}
) {
dispatch({ type: "LOGIN", payload: data });
history.push(`/profile/${data.id}`);
},
onError(err) {
setErrors(err.graphQLErrors[0].extensions.exception.errors);
},
variables: userData
});
const handleSubmit = e => {
e.preventDefault();
addUser();
setUserData({ email: "", password: "" });
};
// Framer motion animations
const PopUp = {
hidden: { x: 1000 },
visible: {
x: 0,
transition: { duration: 0.7 }
}
};
return (
<>
{!loading ? (
<FormAuth
onSubmit={handleSubmit}
variants={PopUp}
initial="hidden"
animate="visible"
>
<TitleAuth>
<TitleAuthImage src={instagram} />
</TitleAuth>
<ContainInput>
<ContainSingleInput top="2rem">
<InputAuth
name="email"
type="email"
placeholder={errors.email ? errors.email : "Email"}
maxLength="50"
value={userData.email}
onChange={e =>
setUserData({ ...userData, email: e.target.value })
}
/>
</ContainSingleInput>
<ContainSingleInput top="7rem">
<InputAuth
name="password"
type="password"
placeholder={errors.password ? errors.password : "Password"}
maxLength="50"
value={userData.password}
onChange={e =>
setUserData({ ...userData, password: e.target.value })
}
/>
</ContainSingleInput>
</ContainInput>
<ContainButtons>
<Button
type="submit"
Login
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.85 }}
>
Login
</Button>
<ButtonSpan
Register
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.85 }}
onClick={() => setLogin(false)}
>
Register
</ButtonSpan>
</ContainButtons>
</FormAuth>
) : (
<Loading />
)}
</>
);
};
const LOGIN_MUTATION = gql`
mutation login($email: String!, $password: String!) {
login(email: $email, password: $password) {
id
email
password
token
}
}
`;
export default Login;
这是登录的样子,那里的凭据是正确的
点击登录后浏览器报错
这里奇怪的是,它以前正常工作,但知道它坏了,我不知道为什么或如何,如果我有错误,它们会出现在输入的占位符中,但要知道,它总是休息
根据 apollo 文档 onError for useMutation passes an ApolloError 其中包含几个元素。
对于当前的实现,您假设 onError
中有这样一个 graphQLErrors
元素,并且它确实填充了至少 1 个元素。情况可能并非如此。出于这个原因,当您尝试访问 err.graphQLErrors[0]
时,您会得到 undefined
,这会导致您的特定错误。
docs 建议在采取行动之前测试特定错误的证据:
onError(({graphQLErrors, networkError}) => {
if (graphQLErrors)
graphQLErrors.forEach(({message, locations, path}) =>
console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
),
);
if (networkError) {
console.log(`[Network error]: ${networkError}`);
}
});
或者,您可以使用 tracking loading and error state
的内置机制const [addUser,
{loading: mutationLoading, error: mutationError}] = useMutation(LOGIN_MUTATION, {
update(
_,
{
data: {login: data}
}
) {
dispatch({type: "LOGIN", payload: data});
history.push(`/profile/${data.id}`);
},
variables: userData
});