React Native、GraphQL、Apollo - 突变期间抛出的错误
Posted
技术标签:
【中文标题】React Native、GraphQL、Apollo - 突变期间抛出的错误【英文标题】:React Native, GraphQL, Apollo - Error thrown during mutation 【发布时间】: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) => console.log("Error caught: " + err)
另外,通过开发控制台,我可以看到正确的变量正在传递,所以它成功了。我无法弄清楚为什么在我从服务器获得成功响应后它会抛出错误。
这个错误意味着某些东西正在搜索 x.variables
并且 x 为空。似乎唯一调用变量的时间是在突变中。你能检查一下查询是否错误地触发了两次,第二次没有传递变量?
@mstorkson 你是对的 - 它出于某种原因发射了两次,尽管我仍然不确定为什么。将其更改为在 AsyncStorage.setItem('token'...) 中包含 createUser 有效。它只触发了一次并返回了积极的响应。我不是 100% 确定为什么会发生这种情况,但至少它现在有效。感谢您的帮助
没问题,很高兴能帮上忙
【参考方案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 函数之后运行了两次。
如果有人有任何想法,请告诉我!
【讨论】:
以上是关于React Native、GraphQL、Apollo - 突变期间抛出的错误的主要内容,如果未能解决你的问题,请参考以下文章
使用 Relay + React Native (create-react-native-app) 时出错:GraphQL 验证错误`未知类型“查看器”。`
仅返回选定字段 React Native / GraphQL / Amplify
无法在 GraphQL 突变中传递数组 - React Native
我如何在 react-native 聊天应用程序中使用 GraphQl 订阅从 GraphQl 查询中获取实时更新