graphql - 根据 react-apollo 中的查询结果更新本地配置
问题描述
使用 apollo 和 react,我想根据(远程)apollo 查询的结果更新我的本地 apollo 状态。
查询是类型的[String!]!
,我的本地状态包含类型的 {name} String
。我想将本地 { name } 分配给查询返回的第一项。
const App = compose(
graphql(gql`{ name @client }`, { name: 'localData' }),
graphql(gql`{ currencies { name } }`)
)(({ localData }) => <h1>{ localData.name }</h1>)
我不想使用componentWillReceiveProps
(一旦道具来自远程查询,就改变本地状态),因为这是不好的做法。
我需要使用本地 apollo 状态,而不仅仅是组件的状态,因为此值将被其他组件使用。
我尝试使用 hoc 的props
配置graphql
,但感觉和 componentWillReceiveProps 一样糟糕,并导致无限循环。
任何想法?
相关版本:
"apollo-boost": "^0.1.19",
"apollo-link-state": "^0.4.2",
"react-apollo": "^2.2.4",
代码
import React from 'react'
import ReactDOM from 'react-dom'
import ApolloClient from 'apollo-boost'
import gql from 'graphql-tag'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloProvider, graphql, compose } from 'react-apollo'
import { ApolloLink } from 'apollo-link'
import { withClientState } from 'apollo-link-state'
import { HttpLink } from 'apollo-link-http'
const resolvers = {
Mutation: {
updateName: (ops, { name }, { cache }) => cache.writeData({ data: { name } })
}
}
const typedefs = gql`
type Query {
name: String
}
type Mutation {
updateName(name: String): String
}
`
const defaults = { name: 'defaultName' }
const cache = new InMemoryCache()
const stateLink = withClientState({
cache,
defaults,
resolvers
});
const apolloClient = new ApolloClient({
uri: '/store/api/graphql',
link: ApolloLink.from([stateLink, new HttpLink()]),
cache,
clientState: {
defaults,
resolvers,
typedefs
}
})
const App = compose(
graphql(gql`{ name @client }`, { name: 'localData' }),
graphql(gql`{ currencies { name id } }`)
)(({ localData }) => <h1>{ localData.name }</h1>)
ReactDOM.render(
<ApolloProvider client={ apolloClient }>
<App />
</ApolloProvider>,
document.getElementById('app')
)
解决方案
我找到了一个使用 Query 组件而不是 graphql hoc 的解决方案。Query 组件具有onCompleted
属性,我可以在其中传递一个更新本地状态的函数:
const UPDATE_NAME = gql`mutation ($name: String) {
updateName (name: $name) @client { name }
}`
const App = compose(
withApollo,
graphql(gql`{ name @client }`, { name: 'localData' })
)(({ client, localData }) => <Query
query={ gql`{ currencies { name id } }` }
onCompleted={ data =>
client.mutate({
mutation: UPDATE_NAME,
variables: { name: data.currencies[0].name }
})
}>
{
() => <h1>Current: { localData.name }</h1>
}
</Query>)
我发现 Query 组件不如 graphql hoc 优雅,但至少是一个解决方案。
推荐阅读
- flutter - 登录后上传 FCM Token
- javascript - 搜索完成后重置表单不起作用
- android-studio-4.1 - 在 Android Studio 中找不到“记录浓缩咖啡测试”
- java - 如果使用管理员用户安装,Install4J 将不会启动应用程序
- odoo-14 - 如何在 ODOO-14 .... 中激活开发者模式?
- ios - 在 Swift/SwiftUI 中仅显示 Date 对象的时间
- html - 无效的 CSS left 属性是否可以接受?
- angularjs-ng-repeat - NG-repeat 在 td 中只显示一次值
- javascript - 循环的斐波那契代码不返回值
- shared-libraries - mpiexec 分段错误地址未映射