【发布时间】:2018-10-05 20:56:17
【问题描述】:
我正在使用 Apollo 2.0 来管理我的 graphQL API 调用并处理我的 react 应用程序的全局状态。
我正在尝试创建一个登录屏幕,用户在其中输入他们的用户名和密码,这将被发送到我的 API 进行身份验证,成功后,我想将isLoggedIn 的全局状态设置为true。
到目前为止,我可以使用@client 声明的一个突变设置全局状态,因此它只关注本地状态。我有另一个突变,它使 graphQL API 调用并验证用户名/密码,然后返回成功/错误响应。
我希望能够在 API 调用突变完成或失败后设置 isLoggedIn。
我的客户端具有以下默认状态和解析器设置如下:
const httpLink = new HttpLink({
uri: '/graphql',
credentials: 'same-origin'
});
const cache = new InMemoryCache();
const stateLink = withClientState({
cache,
resolvers: {
Mutation: {
updateLoggedInStatus: (_, { isLoggedIn }, { cache }) => {
const data = {
loggedInStatus: {
__typename: 'LoggedInStatus',
isLoggedIn
},
};
cache.writeData({ data });
return null;
},
},
},
defaults: {
loggedInStatus: {
__typename: 'LoggedInStatus',
isLoggedIn: false,
},
},
});
const link = ApolloLink.from([stateLink, httpLink])
const client = new ApolloClient({
link,
cache
});
export default client
然后在我的登录组件中,我在 compose 的帮助下将以下突变和查询作为 HOC 传递:
const UPDATE_LOGGED_IN_STATUS = gql`
mutation updateLoggedInStatus($isLoggedIn: Boolean) {
updateLoggedInStatus(isLoggedIn: $isLoggedIn) @client
}`
const AUTHENTICATE = gql`
mutation authenticate($username: String!, $password: String!) {
auth(username: $username, password: $password) {
username
sales_channel
full_name
roles
}
}`
const GET_AUTH_STATUS = gql`
query {
loggedInStatus @client {
isLoggedIn
}
}`
export default compose(
graphql(GET_AUTH_STATUS, {
props: ({ data: { loading, error, loggedInStatus } }) => {
if (loading) {
return { loading };
}
if (error) {
return { error };
}
return {
loading: false,
loggedInStatus
};
},
}),
graphql(UPDATE_LOGGED_IN_STATUS, {
props: ({ mutate }) => ({
updateLoggedInStatus: isLoggedIn => mutate({ variables: { isLoggedIn } }),
}),
}),
graphql(AUTHENTICATE, {
props: ({ mutate }) => ({
authenticate: (username, password) => mutate({ variables: { username, password } }),
}),
})
)(withRouter(Login));
如您所见,我有this.props.authenticate(username, password),在提交登录表单时使用。
然后我有this.props.updateLoggedInStatus(Boolean),我可以更新客户端缓存/状态。
如何组合这些以便我可以调用authenticate(),如果成功,设置loggedInStatus,如果失败,设置hasErrored 或errorMessage 各种标志?
提前致谢。
编辑:
我试图在我的突变回调中处理更新状态。
// Form submission handler
onSubmit = async ({ username, password }) => {
this.setState({loading: true})
this.props.authenticate(username, password)
.then(res => {
this.setState({loading: false})
this.props.updateLoggedInStatus(true)
})
.catch(err => {
this.setState({loading: false, errorMessage: err.message})
console.log('err', err)
})
}
还有比这更好的方法吗?不得不等待回电感觉非常复杂。我原以为我可以通过解析器将响应映射到我的缓存对象?
【问题讨论】:
标签: reactjs graphql apollo react-apollo apollo-client