【问题标题】:React Native, GraphQL, Apollo - Error thrown during mutationReact Native、GraphQL、Apollo - 突变期间抛出的错误
【发布时间】:2017-10-25 05:03:40
【问题描述】:

我正在开发一个以 Apollo 客户端和 GraphQL 作为后端的 React Native 项目。我遇到的问题是,当我使用突变注册新用户时,我得到了用户已创建的肯定响应,但我也得到了一个错误,说 Error catch: TypeError: Cannot read property '未定义的变量

我不确定问题是什么,或者为什么返回错误。代码如下:

'use strict'

import React, { Component } from 'react';
import { Text, View, StyleSheet, AsyncStorage, Modal, TouchableHighlight } from 'react-native'
import { Actions, ActionConst } from 'react-native-router-flux'
import { Button } from 'react-native-elements'

// Apollo and GraphQL Packages
import ApolloClient, { graphql, withApollo } from 'react-apollo'
import gql from 'graphql-tag'
import { filter } from 'graphql-anywhere'
import { connect } from 'react-redux'
import Auth0Lock from 'react-native-lock'

// Styling Packages
import LinearGradient from 'react-native-linear-gradient'
import EStyleSheet from 'react-native-extended-stylesheet'

// View Packages
import ViewContainer from './ViewContainer'

// Auth0 Credentials
const clientId = "XXXX"
const domain = "XXXX"

// Props Declaration
type Props = {
  client: ApolloClient,
  createUser: ({
    variables: {
      idToken: string,
      name: ?string,
      email: ?string
    }
  }) => { id: string}
}

class Login extends Component {
  _lock: Auth0Lock
  props: Props

  constructor(props) {
    super(props)
    this._lock = new Auth0Lock({
      clientId: clientId,
      domain: domain,
      useBrowser: true
    })
  }

  _showLogin() {
    this._lock.show({
      closable: true,
      connections: ['Username-Password-Authentication']
    }, async (err, profile, token) => {
      if (!err) {
        AsyncStorage.setItem('token', token.idToken)
          .then(() => {
            this.props.client.resetStore()
          })
        this.props.createUser({
            variables: {
              idToken: token.idToken,
              name: profile.name
              email: profile.email
            }
          })
          .then((data) => {
            console.log("Data received: " + data)
            Actions.registration({ type: ActionConst.REPLACE })
          })
          .catch((err) => {
            console.log("Error caught: " + err)
            AsyncStorage.removeItem('token')
              .then(() => this.props.client.resetStore())
            // Actions.home({ type: ActionConst.REPLACE })
          })
      } else {
        console.log(err)
      }
    })
  }

  render() {
    return(
      <LinearGradient colors={['#34E89E', '#0F3443']} style={styles.linearGradient}>
        <ViewContainer style={styles.viewContainer}>
          <Button
            small
            raised
            buttonStyle= {styles.button}
            color="#fff"
            title="Login"
            onPress={() => this._showLogin()} />
        </ViewContainer>
      </LinearGradient>
    )
  }
}

const styles = EStyleSheet.create({
  viewContainer: {
    flex: 1,
    paddingTop: 70,
    paddingLeft: 20,
    paddingRight: 20
  },
  linearGradient: {
    height: '$height',
  },
  logo: {
    fontFamily: 'LiberatorHeavy',
    fontSize: 52,
    alignSelf: 'center',
    marginBottom: 400,
    color: 'white',
    backgroundColor: 'transparent'
  },
  button: {
    backgroundColor: '#222222'
  }
});

const createUserMutation = gql`
mutation createUser($idToken: String!, $name: String, $email: String) {
  createUser(
    authProvider: {
      auth0: {
        idToken: $idToken
      }
    },
    name: $name,
    email: $email
  ){
    id
  }
}`

export default withApollo(
  graphql(createUserMutation,
    { name: 'createUser' }
  )(Login))

【问题讨论】:

  • 你确定这个错误特别来自这个组件吗?我会尝试的一件事是在 if 语句中打印出“this.props”,因为“this”在错误的范围内可能很危险,因为它的值是在运行时确定的
  • 是的,我确定这是引发错误的组件 - 特别是这一行:.catch((err) =&gt; {console.log("Error caught: " + err)} 另外,通过开发控制台,我可以看到正确的变量正在传递,所以它成功了。我无法弄清楚为什么在我从服务器获得成功响应后它会抛出错误。
  • 这个错误意味着某些东西正在搜索 x.variables 并且 x 为空。似乎唯一调用变量的时间是在突变中。你能检查一下查询是否错误地触发了两次,第二次没有传递变量?
  • @mstorkson 你是对的 - 它出于某种原因发射了两次,尽管我仍然不确定为什么。将其更改为在 AsyncStorage.setItem('token'...) 中包含 createUser 有效。它只触发了一次并返回了积极的响应。我不是 100% 确定为什么会发生这种情况,但至少它现在有效。感谢您的帮助
  • 没问题,很高兴能帮上忙

标签: javascript react-native graphql apollo react-apollo


【解决方案1】:

所以错误是

createUser({variables...})

函数被触发两次,导致在变量被清除后抛出错误。我将代码更改为:

_showLogin() {
    this._lock.show({
      closable: true,
      connections: ['Username-Password-Authentication']
    }, async (err, profile, token) => {
      if (!err) {
        AsyncStorage.setItem('token', token.idToken)
          .then(() => {
            this.props.client.resetStore()

            // Create user function was put in to AsyncStorage function to stop function from running twice. (Not sure why that was happening)
            this.props.createUser({
                variables: {
                  idToken: token.idToken,
                  name: profile.name,
                  email: profile.email
                }
              })
              .then((data) => {
                console.log("Data received: " + data)
                Actions.registration({ type: ActionConst.REPLACE })
              })
              .catch((err) => {
                console.log("Error caught: " + err)
                AsyncStorage.removeItem('token')
                  .then(() => this.props.client.resetStore())
                // Actions.home({ type: ActionConst.REPLACE })
              })
          })
      } else {
        console.log(err)
      }

这解决了问题,我得到了正确的响应,尽管我仍然不确定为什么它在 Async 函数之后运行了两次。

如果有人有任何想法,请告诉我!

【讨论】:

    猜你喜欢
    • 2018-12-03
    • 2019-04-14
    • 1970-01-01
    • 2021-03-11
    • 2018-12-27
    • 2020-11-04
    • 2018-08-26
    • 2017-11-20
    • 2020-04-24
    相关资源
    最近更新 更多