反应中的奇怪错误-使用阿波罗/客户端-graphql

Posted

技术标签:

【中文标题】反应中的奇怪错误-使用阿波罗/客户端-graphql【英文标题】:Weird error in react - using apollo/client - graphql 【发布时间】:2021-07-13 01:44:34 【问题描述】:

我正在开发一个 MERNG 应用程序,到目前为止一切正常,但是我在 useMutations 前面遇到了一些错误,让我向你解释一下。

因此,在登录/注册部分,如果您将字段留空或在登录名中,如果在数据库中找不到您的用户,则会给出错误,并且我会在函数 onError(err) 中收到这些错误,但是,问题是,它总是给我错误,它说,无法读取未定义的属性“扩展”,即使我没有错误,它也会给出错误,让我给你看代码

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;

这是登录的样子,那里的凭据是正确的

点击登录后浏览器报错

这里奇怪的部分是,它以前正常工作,但知道它坏了,我不知道为什么或如何,如果我有错误,它们会出现在输入的 placeHolder 中,但知道,它总是坏

【问题讨论】:

添加对graphQl错误对象的检查将防止崩溃,例如:` if (err.graphQLErrors[0]) setErrors(err.graphQLErrors[0].extensions.exception.errors); ` 或者直接使用useMutation中的错误对象[addUser, loading, error ] = useMutation() 谢谢,它帮助我解决了我的错误! 【参考方案1】:

根据阿波罗文档onError for useMutation 传递一个包含多个元素的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
);

【讨论】:

以上是关于反应中的奇怪错误-使用阿波罗/客户端-graphql的主要内容,如果未能解决你的问题,请参考以下文章

表达 http:graphql 突变上的 500 错误以在反应中从阿波罗客户端创建用户

使用阿波罗客户端上传图像时获取网络请求失败反应原生android

阿波罗客户端在反应原生的初始重新加载中返回未定义

将数据发送回阿波罗服务器时出错(错误请求错误)

如何在 x 时间后重新渲染反应(突变阿波罗)

突变后反应阿波罗不更新数据